From fijal at codespeak.net Mon Mar 1 02:08:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 02:08:30 +0100 (CET) Subject: [pypy-svn] r71576 - pypy/trunk/pypy/rlib Message-ID: <20100301010830.A7A9451054@codespeak.net> Author: fijal Date: Mon Mar 1 02:08:28 2010 New Revision: 71576 Modified: pypy/trunk/pypy/rlib/rmarshal.py Log: Force this to be not-necesarilly-nonneg Modified: pypy/trunk/pypy/rlib/rmarshal.py ============================================================================== --- pypy/trunk/pypy/rlib/rmarshal.py (original) +++ pypy/trunk/pypy/rlib/rmarshal.py Mon Mar 1 02:08:28 2010 @@ -261,6 +261,7 @@ loader.need_more_data() loader.pos = end return loader.buf[pos:end] +readstr._annenforceargs_ = [None, int] def readchr(loader): pos = loader.pos From fijal at codespeak.net Mon Mar 1 03:39:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 03:39:08 +0100 (CET) Subject: [pypy-svn] r71577 - pypy/trunk/pypy/rlib Message-ID: <20100301023908.5141951054@codespeak.net> Author: fijal Date: Mon Mar 1 03:38:56 2010 New Revision: 71577 Modified: pypy/trunk/pypy/rlib/rmmap.py Log: I think this is a correct fix for JIT & sandbox - we assumer mmap and friends are sandbox-safe (they can only work on existing file descs anyway). If we compile mmap module, this will probably violate sandbox, but we compile sandbox with no-allworkingmodules anyway Modified: pypy/trunk/pypy/rlib/rmmap.py ============================================================================== --- pypy/trunk/pypy/rlib/rmmap.py (original) +++ pypy/trunk/pypy/rlib/rmmap.py Mon Mar 1 03:38:56 2010 @@ -92,10 +92,11 @@ def external(name, args, result): return rffi.llexternal(name, args, result, - compilation_info=CConfig._compilation_info_) + compilation_info=CConfig._compilation_info_, + sandboxsafe=True, threadsafe=True) def winexternal(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win') + return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', sandboxsafe=True, threadsafe=True) PTR = rffi.CCHARP From fijal at codespeak.net Mon Mar 1 04:06:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 04:06:08 +0100 (CET) Subject: [pypy-svn] r71578 - in pypy/trunk/pypy: jit/backend/x86 rlib/rsre Message-ID: <20100301030608.0F4D451054@codespeak.net> Author: fijal Date: Mon Mar 1 04:05:53 2010 New Revision: 71578 Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py pypy/trunk/pypy/jit/backend/x86/valgrind.py pypy/trunk/pypy/rlib/rsre/_rsre_platform.py Log: Sprinkle sandboxsafe here and there Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/codebuf.py (original) +++ pypy/trunk/pypy/jit/backend/x86/codebuf.py Mon Mar 1 04:05:53 2010 @@ -155,4 +155,5 @@ separate_module_sources = ['void PYPY_NO_OP(void) {}'], ) ensure_sse2_floats = rffi.llexternal('PYPY_NO_OP', [], lltype.Void, - compilation_info=_sse2_eci) + compilation_info=_sse2_eci, + sandboxsafe=True) Modified: pypy/trunk/pypy/jit/backend/x86/valgrind.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/valgrind.py (original) +++ pypy/trunk/pypy/jit/backend/x86/valgrind.py Mon Mar 1 04:05:53 2010 @@ -20,7 +20,8 @@ [llmemory.Address, lltype.Signed], lltype.Void, compilation_info=eci, - _nowrapper=True) + _nowrapper=True, + sandboxsafe=True) # ____________________________________________________________ Modified: pypy/trunk/pypy/rlib/rsre/_rsre_platform.py ============================================================================== --- pypy/trunk/pypy/rlib/rsre/_rsre_platform.py (original) +++ pypy/trunk/pypy/rlib/rsre/_rsre_platform.py Mon Mar 1 04:05:53 2010 @@ -10,7 +10,8 @@ return rffi.llexternal(name, args, result, compilation_info=eci, **kwds) tolower = external('tolower', [lltype.Signed], lltype.Signed, - oo_primitive='tolower') + oo_primitive='tolower', + sandboxsafe=True) isalnum = external('isalnum', [lltype.Signed], lltype.Signed, - oo_primitive='isalnum') + oo_primitive='isalnum', sandboxsafe=True) From fijal at codespeak.net Mon Mar 1 05:14:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 05:14:48 +0100 (CET) Subject: [pypy-svn] r71579 - pypy/trunk/pypy/module/_weakref Message-ID: <20100301041448.6F4C451054@codespeak.net> Author: fijal Date: Mon Mar 1 05:14:30 2010 New Revision: 71579 Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py Log: kill IMO useless use of __args__ Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/interp__weakref.py Mon Mar 1 05:14:30 2010 @@ -143,11 +143,7 @@ return w_obj -def descr__new__weakref(space, w_subtype, w_obj, __args__): - if __args__.arguments_w: - w_callable = __args__.arguments_w[0] - else: - w_callable = space.w_None +def descr__new__weakref(space, w_subtype, w_obj, w_callable=None): lifeline = w_obj.getweakref() if lifeline is None: lifeline = WeakrefLifeline(space) @@ -188,7 +184,7 @@ which is called with the weak reference as an argument when 'obj' is about to be finalized.""", __new__ = interp2app(descr__new__weakref, - unwrap_spec=[ObjSpace, W_Root, W_Root, Arguments]), + unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root]), __eq__ = interp2app(descr__eq__, unwrap_spec=[ObjSpace, W_Weakref, W_Root]), __ne__ = interp2app(descr__ne__, From fijal at codespeak.net Mon Mar 1 05:30:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 05:30:18 +0100 (CET) Subject: [pypy-svn] r71580 - pypy/trunk/pypy/module/_weakref Message-ID: <20100301043018.988C651054@codespeak.net> Author: fijal Date: Mon Mar 1 05:30:03 2010 New Revision: 71580 Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py Log: Revert 71579, it breaks tests Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/interp__weakref.py Mon Mar 1 05:30:03 2010 @@ -141,9 +141,12 @@ if w_obj is None: return self.space.w_None 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__): + if __args__.arguments_w: + w_callable = __args__.arguments_w[0] + else: + w_callable = space.w_None lifeline = w_obj.getweakref() if lifeline is None: lifeline = WeakrefLifeline(space) @@ -184,7 +187,7 @@ which is called with the weak reference as an argument when 'obj' is about to be finalized.""", __new__ = interp2app(descr__new__weakref, - unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root]), + unwrap_spec=[ObjSpace, W_Root, W_Root, Arguments]), __eq__ = interp2app(descr__eq__, unwrap_spec=[ObjSpace, W_Weakref, W_Root]), __ne__ = interp2app(descr__ne__, From fijal at codespeak.net Mon Mar 1 06:43:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 06:43:06 +0100 (CET) Subject: [pypy-svn] r71581 - pypy/trunk/pypy/jit/tool Message-ID: <20100301054306.EE28551054@codespeak.net> Author: fijal Date: Mon Mar 1 06:42:57 2010 New Revision: 71581 Modified: pypy/trunk/pypy/jit/tool/otherviewer.py Log: handle ratio=0 case Modified: pypy/trunk/pypy/jit/tool/otherviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/otherviewer.py Mon Mar 1 06:42:57 2010 @@ -57,6 +57,8 @@ shape='box', fillcolor=get_gradient_color(self.ratio)) def get_gradient_color(ratio): + if ratio == 0: + return 'white' ratio = math.log(ratio) # from -infinity to +infinity # # ratio: <---------------------- 1.8 ---------------------> From fijal at codespeak.net Mon Mar 1 06:59:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 1 Mar 2010 06:59:15 +0100 (CET) Subject: [pypy-svn] r71582 - pypy/trunk/pypy/module/_weakref Message-ID: <20100301055915.2CD3551054@codespeak.net> Author: fijal Date: Mon Mar 1 06:59:08 2010 New Revision: 71582 Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py Log: Another approach to make JIT not allocate unnecessary __args__ (calling _combine_wrapped). Revert if breaks any apptests Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/interp__weakref.py Mon Mar 1 06:59:08 2010 @@ -142,11 +142,8 @@ return self.space.w_None return w_obj -def descr__new__weakref(space, w_subtype, w_obj, __args__): - if __args__.arguments_w: - w_callable = __args__.arguments_w[0] - else: - w_callable = space.w_None +def descr__new__weakref(space, w_subtype, w_obj, w_callable=None, + __args__=None): lifeline = w_obj.getweakref() if lifeline is None: lifeline = WeakrefLifeline(space) @@ -187,7 +184,8 @@ which is called with the weak reference as an argument when 'obj' is about to be finalized.""", __new__ = interp2app(descr__new__weakref, - unwrap_spec=[ObjSpace, W_Root, W_Root, Arguments]), + unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, + Arguments]), __eq__ = interp2app(descr__eq__, unwrap_spec=[ObjSpace, W_Weakref, W_Root]), __ne__ = interp2app(descr__ne__, From arigo at codespeak.net Mon Mar 1 09:31:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 09:31:47 +0100 (CET) Subject: [pypy-svn] r71583 - in pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc: . test test/darwin test/elf test/msvc Message-ID: <20100301083147.62D4951054@codespeak.net> Author: arigo Date: Mon Mar 1 09:31:43 2010 New Revision: 71583 Added: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/darwin/track9.s pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track9.s pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track9.s Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Log: Add tests for GC_NOCOLLECT calls. Small fix to prevent any resume data from being generated around such calls. Added: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/darwin/track9.s ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/darwin/track9.s Mon Mar 1 09:31:43 2010 @@ -0,0 +1,18 @@ +_pypy_g_foo: +L1506: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + call L103 +"L00000000006$pb": +L103: + popl %ebx + call _open + /* GC_NOCOLLECT open */ + popl %ebx + popl %esi + popl %edi + popl %ebp + ret + .align 4,0x90 Added: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track9.s ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track9.s Mon Mar 1 09:31:43 2010 @@ -0,0 +1,23 @@ + .type pypy_g_stuff, @function +pypy_g_stuff: +.LFB41: + .loc 2 1513 0 + pushl %ebp +.LCFI87: + movl %esp, %ebp +.LCFI88: + subl $72, %esp +.LCFI89: +.L543: + .loc 2 1521 0 + movl $420, 8(%esp) + movl $0, 4(%esp) + movl $pypy_g_array_16, (%esp) + call open + /* GC_NOCOLLECT open */ +.L542: + .loc 2 1588 0 + leave + ret +.LFE41: + .size pypy_g_stuff, .-pypy_g_stuff Added: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track9.s ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track9.s Mon Mar 1 09:31:43 2010 @@ -0,0 +1,26 @@ +; Function compile flags: /Ogtpy +; COMDAT _pypy_g_ll_join_strs__Signed_arrayPtr +_TEXT SEGMENT +_pypy_g_ll_join_strs__Signed_arrayPtr PROC ; COMDAT + +; 1457 : struct pypy_rpy_string0 *pypy_g_ll_join_strs__Signed_arrayPtr(long l_num_items_0, struct pypy_array0 *l_items_2) { + + sub esp, 8 + push ebx + push ebp + push esi + +; 1458 : pypy_asm_gc_nocollect(open); + + call _open + pop esi + pop ebp +$block4$40052: + pop ebx + +; 1535 : goto block1_back; +; 1536 : } + + add esp, 8 + ret 0 +_pypy_g_ll_join_strs__Signed_arrayPtr ENDP Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/test_trackgcroot.py Mon Mar 1 09:31:43 2010 @@ -169,6 +169,9 @@ assert len(seen) == len(tabledict), ( "computed table contains unexpected entries:\n%r" % [key for key in tabledict if key not in seen]) - print lines - print expectedlines + print '--------------- got ---------------' + print ''.join(lines) + print '------------- expected ------------' + print ''.join(expectedlines) + print '-----------------------------------' assert lines == expectedlines Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Mon Mar 1 09:31:43 2010 @@ -44,7 +44,7 @@ self.findlabels() self.parse_instructions() try: - if not self.list_call_insns(): + if not self.list_collecting_call_insns(): return [] self.find_noncollecting_calls() self.findframesize() @@ -64,11 +64,9 @@ See format_callshape() for more details about callshape_tuple. """ table = [] - for insn in self.list_call_insns(): + for insn in self.list_collecting_call_insns(): if not hasattr(insn, 'framesize'): continue # calls that never end up reaching a RET - if insn.name in self.cannot_collect: - continue if self.is_stack_bottom: retaddr = LOC_NOWHERE # end marker for asmgcroot.py elif self.uses_frame_pointer: @@ -193,8 +191,9 @@ raise UnrecognizedOperation(opname) setattr(cls, 'visit_' + opname, cls.visit_nop) - def list_call_insns(self): - return [insn for insn in self.insns if isinstance(insn, InsnCall)] + def list_collecting_call_insns(self): + return [insn for insn in self.insns if isinstance(insn, InsnCall) + if insn.name not in self.cannot_collect] def findframesize(self): # the 'framesize' attached to an instruction is the number of bytes @@ -306,7 +305,7 @@ # walk backwards, because inserting the global labels in self.lines # is going to invalidate the lineno of all the InsnCall objects # after the current one. - for call in self.list_call_insns()[::-1]: + for call in self.list_collecting_call_insns()[::-1]: if hasattr(call, 'framesize'): self.create_global_label(call) From arigo at codespeak.net Mon Mar 1 10:29:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 10:29:55 +0100 (CET) Subject: [pypy-svn] r71584 - in pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc: . test/elf test/msvc Message-ID: <20100301092955.1955651054@codespeak.net> Author: arigo Date: Mon Mar 1 10:29:52 2010 New Revision: 71584 Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track5.s pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track0.s pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Log: Improve by keeping out a few functions -- e.g. RPyAbort cannot collect. Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/instruction.py Mon Mar 1 10:29:52 2010 @@ -194,8 +194,8 @@ def source_of(self, localvar, tag): tag1 = self.gcroots.setdefault(localvar, tag) assert tag1 == tag, ( - "conflicting entries for InsnCall.gcroots[%s]:\n%r and %r" % ( - localvar, tag1, tag)) + "conflicting entries for\n%s.gcroots[%s]:\n%r and %r" % ( + self, localvar, tag1, tag)) return localvar def all_sources_of(self, localvar): Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track5.s ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track5.s (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track5.s Mon Mar 1 10:29:52 2010 @@ -42,9 +42,9 @@ call pypy_g_SemiSpaceGC_get_size ;; expected {28(%esp) | 20(%esp), 24(%esp), %edi, %ebp | } addl %eax, %ebx + jmp .L1221 .L1227: call RPyAbort - ;; expected {28(%esp) | 20(%esp), 24(%esp), %edi, %ebp | } cmpl 12(%esi), %ebx jb .L1229 addl $20, %esp Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track0.s ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track0.s (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track0.s Mon Mar 1 10:29:52 2010 @@ -64,7 +64,6 @@ jl SHORT $LN15 at pypy_g_ll_@139 $LN14 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | 32(%esp)} $LN15 at pypy_g_ll_@139: ; 1529 : l_v420 = l_v419; @@ -76,7 +75,6 @@ test ebx, ebx jne SHORT $LN16 at pypy_g_ll_@139 call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | 32(%esp)} $LN16 at pypy_g_ll_@139: ; 1531 : OP_INT_ADD(l_v402, l_v421, l_v422); @@ -183,7 +181,6 @@ jl SHORT $LN10 at pypy_g_ll_@139 $LN9 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN10 at pypy_g_ll_@139: ; 1517 : l_v413 = l_v412; @@ -195,7 +192,6 @@ test edi, edi jne SHORT $LN11 at pypy_g_ll_@139 call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN11 at pypy_g_ll_@139: mov edi, DWORD PTR [edi+8] @@ -208,7 +204,6 @@ jl SHORT $LN13 at pypy_g_ll_@139 $LN12 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN13 at pypy_g_ll_@139: ; 1520 : pypy_g_copy_string_contents__rpy_stringPtr_rpy_stringPt(l_v415, l_result_2, 0L, l_res_index_0, l_v414); Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Mon Mar 1 10:29:52 2010 @@ -38,15 +38,14 @@ self.filetag = filetag # a "stack bottom" function is either main() or a callback from C code self.is_stack_bottom = False - self.cannot_collect = {} def computegcmaptable(self, verbose=0): self.findlabels() self.parse_instructions() try: + self.find_noncollecting_calls() if not self.list_collecting_call_insns(): return [] - self.find_noncollecting_calls() self.findframesize() self.fixlocalvars() self.trackgcroots() @@ -120,13 +119,18 @@ self.labels[label] = Label(label, lineno) def find_noncollecting_calls(self): + cannot_collect = self.CANNOT_COLLECT.copy() for line in self.lines: match = self.r_gcnocollect_marker.search(line) if match: name = match.group(1) - if self.format in ('darwin', 'mingw32', 'msvc'): - name = '_' + name - self.cannot_collect[name] = True + cannot_collect[name] = True + # + if self.format in ('darwin', 'mingw32', 'msvc'): + self.cannot_collect = dict.fromkeys( + ['_' + name for name in cannot_collect]) + else: + self.cannot_collect = cannot_collect def append_instruction(self, insn): # Add the instruction to the list, and link it to the previous one. @@ -347,6 +351,12 @@ # ____________________________________________________________ + CANNOT_COLLECT = { # some of the most used functions that cannot collect + 'pypy_debug_catch_fatal_exception': None, + 'RPyAbort': None, + 'RPyAssertFailed': None, + } + def _visit_gcroot_marker(self, line): match = self.r_gcroot_marker.match(line) loc = match.group(1) @@ -839,7 +849,6 @@ '__imp___wassert': None, 'DWORD PTR __imp__abort': None, 'DWORD PTR __imp___wassert': None, - '_pypy_debug_catch_fatal_exception': None, } @classmethod From arigo at codespeak.net Mon Mar 1 10:40:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 10:40:02 +0100 (CET) Subject: [pypy-svn] r71585 - in pypy/trunk/pypy: jit/backend/x86 rlib rlib/rsre Message-ID: <20100301094002.0C19351054@codespeak.net> Author: arigo Date: Mon Mar 1 10:40:00 2010 New Revision: 71585 Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py pypy/trunk/pypy/jit/backend/x86/valgrind.py pypy/trunk/pypy/rlib/rmmap.py pypy/trunk/pypy/rlib/rsre/_rsre_platform.py Log: Revert r71577 and r71578. See branch. Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/codebuf.py (original) +++ pypy/trunk/pypy/jit/backend/x86/codebuf.py Mon Mar 1 10:40:00 2010 @@ -155,5 +155,4 @@ separate_module_sources = ['void PYPY_NO_OP(void) {}'], ) ensure_sse2_floats = rffi.llexternal('PYPY_NO_OP', [], lltype.Void, - compilation_info=_sse2_eci, - sandboxsafe=True) + compilation_info=_sse2_eci) Modified: pypy/trunk/pypy/jit/backend/x86/valgrind.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/valgrind.py (original) +++ pypy/trunk/pypy/jit/backend/x86/valgrind.py Mon Mar 1 10:40:00 2010 @@ -20,8 +20,7 @@ [llmemory.Address, lltype.Signed], lltype.Void, compilation_info=eci, - _nowrapper=True, - sandboxsafe=True) + _nowrapper=True) # ____________________________________________________________ Modified: pypy/trunk/pypy/rlib/rmmap.py ============================================================================== --- pypy/trunk/pypy/rlib/rmmap.py (original) +++ pypy/trunk/pypy/rlib/rmmap.py Mon Mar 1 10:40:00 2010 @@ -92,11 +92,10 @@ def external(name, args, result): return rffi.llexternal(name, args, result, - compilation_info=CConfig._compilation_info_, - sandboxsafe=True, threadsafe=True) + compilation_info=CConfig._compilation_info_) def winexternal(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', sandboxsafe=True, threadsafe=True) + return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win') PTR = rffi.CCHARP Modified: pypy/trunk/pypy/rlib/rsre/_rsre_platform.py ============================================================================== --- pypy/trunk/pypy/rlib/rsre/_rsre_platform.py (original) +++ pypy/trunk/pypy/rlib/rsre/_rsre_platform.py Mon Mar 1 10:40:00 2010 @@ -10,8 +10,7 @@ return rffi.llexternal(name, args, result, compilation_info=eci, **kwds) tolower = external('tolower', [lltype.Signed], lltype.Signed, - oo_primitive='tolower', - sandboxsafe=True) + oo_primitive='tolower') isalnum = external('isalnum', [lltype.Signed], lltype.Signed, - oo_primitive='isalnum', sandboxsafe=True) + oo_primitive='isalnum') From arigo at codespeak.net Mon Mar 1 10:40:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 10:40:19 +0100 (CET) Subject: [pypy-svn] r71586 - pypy/branch/jit-sandbox Message-ID: <20100301094019.147F951054@codespeak.net> Author: arigo Date: Mon Mar 1 10:40:18 2010 New Revision: 71586 Added: pypy/branch/jit-sandbox/ - copied from r71585, pypy/trunk/ Log: A branch in which to make the JIT cooperate with sandboxing. From arigo at codespeak.net Mon Mar 1 10:42:07 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 10:42:07 +0100 (CET) Subject: [pypy-svn] r71587 - in pypy/branch/jit-sandbox/pypy: jit/backend/x86 rlib rlib/rsre Message-ID: <20100301094207.D1EB051054@codespeak.net> Author: arigo Date: Mon Mar 1 10:42:06 2010 New Revision: 71587 Modified: pypy/branch/jit-sandbox/pypy/jit/backend/x86/codebuf.py pypy/branch/jit-sandbox/pypy/jit/backend/x86/valgrind.py pypy/branch/jit-sandbox/pypy/rlib/rmmap.py pypy/branch/jit-sandbox/pypy/rlib/rsre/_rsre_platform.py Log: Repeat r71577 and r71578: (fijal) I think this is a correct fix for JIT & sandbox - we assumer mmap and friends are sandbox-safe (they can only work on existing file descs anyway). If we compile mmap module, this will probably violate sandbox, but we compile sandbox with no-allworkingmodules anyway Sprinkle sandboxsafe here and there Modified: pypy/branch/jit-sandbox/pypy/jit/backend/x86/codebuf.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/jit/backend/x86/codebuf.py (original) +++ pypy/branch/jit-sandbox/pypy/jit/backend/x86/codebuf.py Mon Mar 1 10:42:06 2010 @@ -155,4 +155,5 @@ separate_module_sources = ['void PYPY_NO_OP(void) {}'], ) ensure_sse2_floats = rffi.llexternal('PYPY_NO_OP', [], lltype.Void, - compilation_info=_sse2_eci) + compilation_info=_sse2_eci, + sandboxsafe=True) Modified: pypy/branch/jit-sandbox/pypy/jit/backend/x86/valgrind.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/jit/backend/x86/valgrind.py (original) +++ pypy/branch/jit-sandbox/pypy/jit/backend/x86/valgrind.py Mon Mar 1 10:42:06 2010 @@ -20,7 +20,8 @@ [llmemory.Address, lltype.Signed], lltype.Void, compilation_info=eci, - _nowrapper=True) + _nowrapper=True, + sandboxsafe=True) # ____________________________________________________________ Modified: pypy/branch/jit-sandbox/pypy/rlib/rmmap.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/rlib/rmmap.py (original) +++ pypy/branch/jit-sandbox/pypy/rlib/rmmap.py Mon Mar 1 10:42:06 2010 @@ -92,10 +92,11 @@ def external(name, args, result): return rffi.llexternal(name, args, result, - compilation_info=CConfig._compilation_info_) + compilation_info=CConfig._compilation_info_, + sandboxsafe=True, threadsafe=True) def winexternal(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win') + return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', sandboxsafe=True, threadsafe=True) PTR = rffi.CCHARP Modified: pypy/branch/jit-sandbox/pypy/rlib/rsre/_rsre_platform.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/rlib/rsre/_rsre_platform.py (original) +++ pypy/branch/jit-sandbox/pypy/rlib/rsre/_rsre_platform.py Mon Mar 1 10:42:06 2010 @@ -10,7 +10,8 @@ return rffi.llexternal(name, args, result, compilation_info=eci, **kwds) tolower = external('tolower', [lltype.Signed], lltype.Signed, - oo_primitive='tolower') + oo_primitive='tolower', + sandboxsafe=True) isalnum = external('isalnum', [lltype.Signed], lltype.Signed, - oo_primitive='isalnum') + oo_primitive='isalnum', sandboxsafe=True) From tobami at codespeak.net Mon Mar 1 10:48:38 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Mon, 1 Mar 2010 10:48:38 +0100 (CET) Subject: [pypy-svn] r71588 - in codespeed: pyspeed/codespeed pyspeed/media/css pyspeed/templates tools Message-ID: <20100301094838.8FA6E51054@codespeak.net> Author: tobami Date: Mon Mar 1 10:48:36 2010 New Revision: 71588 Added: codespeed/tools/test_saveresults.py Removed: codespeed/tools/test.py Modified: codespeed/pyspeed/codespeed/views.py codespeed/pyspeed/media/css/main.css codespeed/pyspeed/templates/overview.html codespeed/pyspeed/templates/overview_table.html codespeed/pyspeed/templates/timeline.html codespeed/tools/import_from_json.py codespeed/tools/saveresults.py Log: fix IE. various changes Modified: codespeed/pyspeed/codespeed/views.py ============================================================================== --- codespeed/pyspeed/codespeed/views.py (original) +++ codespeed/pyspeed/codespeed/views.py Mon Mar 1 10:48:36 2010 @@ -99,11 +99,11 @@ revision = int(request.GET["revision"]) lastrevisions = Revision.objects.filter( project=settings.PROJECT_NAME - ).filter(number__lte=revision).order_by('-number')[:11] + ).filter(number__lte=revision).order_by('-number')[:trendconfig+1] lastrevision = lastrevisions[0].number changerevision = lastrevisions[1].number pastrevisions = lastrevisions[trendconfig-2:trendconfig+1] - + print pastrevisions result_list = Result.objects.filter( revision__number=lastrevision ).filter( @@ -167,6 +167,7 @@ relative = c[0].value / result table_list.append({ 'benchmark': bench.name, + 'bench_description': bench.description, 'result': result, 'change': change, 'trend': trend, @@ -182,6 +183,9 @@ # Configuration of default parameters defaulthost = 1 + defaultchangethres = 3 + defaulttrendthres = 3 + defaultcompthres = 0.2 defaulttrend = 10 trends = [5, 10, 20, 100] if data.has_key("trend"): Modified: codespeed/pyspeed/media/css/main.css ============================================================================== --- codespeed/pyspeed/media/css/main.css (original) +++ codespeed/pyspeed/media/css/main.css Mon Mar 1 10:48:36 2010 @@ -23,8 +23,12 @@ div#title h1 { line-height: 72px; margin: 0; font-style: italic; } div#wrapper { margin: 0; } -div#nav ul { margin: 0; padding: 0; padding-left: 15.3em; } -div#nav li { display: inline-block; } +div#nav ul { + display: inline; + margin: 0; padding: 0; padding-left: 15.3em; + font-family: Verdana, sans-serif; +} +div#nav li { display: inline-block; list-style: none; } div#nav ul li a:link, div#nav ul li a:visited { display: block; @@ -33,7 +37,6 @@ text-align: center; background-color: #DADADA; color: #888888; -/* padding: 1em; */ padding-top: 0.6em; padding-bottom: 0.3em; -moz-border-radius-topleft: 20px; @@ -123,9 +126,15 @@ margin: 0; padding: 0.2em; } +.boxbody ul li ul { margin: 0; padding: 0; } +.boxbody ul li ul h4 { margin: 0 0 0.4em; padding: 0; font-size: 1em; font-weight: normal;} +.boxbody ul li ul li { margin-left: 1em; } .boxbody input[type="radio"] { margin-left: 0; } .boxbody input[type="checkbox"] { margin-left: 0; } - +.boxbody label { vertical-align: top; } +.boxbody input[type="text"] { + margin-left: 0; margin-right: 2.5em; margin-bottom: 0.2em; float: right; width: 2em; +} /* tables */ table.tablesorter { width: 100%; @@ -211,7 +220,7 @@ table.tablesorter tbody tr td.status-red { background-color: #FF5640; } table.tablesorter tbody tr td.status-green { background-color: #9FD54D; } -table.tablesorter tbody tr td.status-yellow { background-color: #FEE772; } +/* table.tablesorter tbody tr td.status-yellow { background-color: #FEE772; } */ table.tablesorter tbody tr.highlight td { background-color: #9DADC6 !important; cursor: pointer; @@ -230,3 +239,5 @@ clear: both; height: 0; } +* html .clearfix { zoom: 1; } /* IE6 */ +*:first-child+html .clearfix { zoom: 1; } /* IE7 */ \ No newline at end of file Modified: codespeed/pyspeed/templates/overview.html ============================================================================== --- codespeed/pyspeed/templates/overview.html (original) +++ codespeed/pyspeed/templates/overview.html Mon Mar 1 10:48:36 2010 @@ -22,23 +22,43 @@ window.location="/timeline/?" + ued_encode(conf); } - function updateTable() { + function isNumeric(textvalue) { + if (textvalue.match(/^\d+$/) == null) + return false; + else + return true; + } + + function getColorcode(change, theigh, tlow) { + var colorcode = "status-yellow"; + if(change < tlow) { colorcode = "status-red"; } + else if(change > theigh) { colorcode = "status-green"; } + return colorcode; + } + + function colorTable() { + var changethres = {{ defaultchangethres }}; + var trendthres = {{ defaulttrendthres }}; + var compthres = {{ defaultcompthres }}; $("#results > tbody > tr").each(function() { //Color change column var change = $(this).children("td:eq(2)").text().slice(0, -1); - var colorcode = "status-yellow"; - if(change > 0.3) { colorcode = "status-red"; } - else if(change < -0.3) { colorcode = "status-green"; } - $(this).children("td:eq(2)").addClass(colorcode); + $(this).children("td:eq(2)").addClass(getColorcode(-change, changethres, -changethres)); + //Color trend column + var trend = $(this).children("td:eq(3)").text().slice(0, -1); + $(this).children("td:eq(3)").addClass(getColorcode(-trend, trendthres, -trendthres)); //Color comparison column - var comp = parseFloat($(this).children("td:eq(4)").text()) - colorcode = "status-yellow"; - if(comp < 0.8) { colorcode = "status-red"; } - else if(comp > 1.2) { colorcode = "status-green"; } - $(this).children("td:eq(4)").addClass(colorcode); + var comp = parseFloat($(this).children("td:eq(4)").text()); + $(this).children("td:eq(4)").addClass(getColorcode(comp, 1+compthres, 1-compthres)); + }); + } + + function updateTable() { + colorTable(); + $("#results > tbody > tr").each(function() { //Size plot bars var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); - var bar = transToLogBars(58, tdwidth, comp); + var bar = transToLogBars(58, tdwidth, parseFloat($(this).children("td:eq(4)").text())); $(this).children("td:eq(5)").find("span").css("width", bar["width"]).css("margin-left", bar["margin"]); //Link rows to timelines $(this).click(function () { @@ -78,7 +98,6 @@ $("input[name='interpreter']").change(refreshContent); $("input:radio[name=host]").filter('[value={{ defaulthost }}]').attr('checked', true); $("input[name='host']").change(refreshContent); - refreshContent(); }); Modified: codespeed/pyspeed/templates/overview_table.html ============================================================================== --- codespeed/pyspeed/templates/overview_table.html (original) +++ codespeed/pyspeed/templates/overview_table.html Mon Mar 1 10:48:36 2010 @@ -6,7 +6,7 @@ {% for row in table_list %} - {{ row.benchmark }}{{ row.result|floatformat:3 }}{{ row.change|floatformat:2 }}%{{ row.trend }}{% ifnotequal row.trend "-" %}%{% endifnotequal %}{{ row.relative|floatformat:2 }}- + {{ row.benchmark }}{{ row.result|floatformat:3 }}{{ row.change|floatformat:2 }}%{{ row.trend }}{% ifnotequal row.trend "-" %}%{% endifnotequal %}{{ row.relative|floatformat:2 }}- {% endfor %} \ No newline at end of file Modified: codespeed/pyspeed/templates/timeline.html ============================================================================== --- codespeed/pyspeed/templates/timeline.html (original) +++ codespeed/pyspeed/templates/timeline.html Mon Mar 1 10:48:36 2010 @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block title %}PyPy Speed Center: Timeline{% endblock %} {% block script %} - + Modified: codespeed/tools/import_from_json.py ============================================================================== --- codespeed/tools/import_from_json.py (original) +++ codespeed/tools/import_from_json.py Mon Mar 1 10:48:36 2010 @@ -7,7 +7,8 @@ RESULTS_URL = 'http://buildbot.pypy.org/bench_results/' SPEEDURL = 'http://speed.pypy.org/' SAVE_CPYTHON = False -START_REV = 71480 +START_REV = 71557 +INTERP = "pypy-c-jit" def saveresult(data): params = urllib.urlencode(data) @@ -60,7 +61,7 @@ current_date = datetime.today() proj = 'pypy' revision = result['revision'] - interpreter = "pypy-c-jit" + interpreter = INTERP int_options = "gc=hybrid" if result.has_key('branch'): if result['branch'] != 'trunk': Modified: codespeed/tools/saveresults.py ============================================================================== --- codespeed/tools/saveresults.py (original) +++ codespeed/tools/saveresults.py Mon Mar 1 10:48:36 2010 @@ -1,28 +1,15 @@ # -*- coding: utf-8 -*- import urllib, urllib2 from datetime import datetime -import logging, logging.handlers - -## SETUP LOGS ## -LOG_FILENAME = 'pyspeed.log' -logger = logging.getLogger('MyLogger') -logger.setLevel(logging.DEBUG) -# Add the log message handler to the logger -handler = logging.handlers.RotatingFileHandler( - LOG_FILENAME, maxBytes=100000, backupCount=1) -logger.addHandler(handler) -################ SPEEDURL = "http://speed.pypy.org/" HOST = "bigdog" -def save(revision, results, options, branch, interpreter, int_options): +def save(project, revision, results, options, branch, interpreter, int_options, testing=False): + testparams = [] #Parse data data = {} current_date = datetime.today() - proj = "pypy" - #interpreter = "pypy-c-jit" - #int_options = "gc=hybrid" if branch != "" and branch != "trunk": interpreter = branch int_options = "" @@ -37,11 +24,11 @@ elif res_type == "ComparisonResult": value = results['avg_changed'] else: - logger.critical("ERROR: result type unknown " + b[1]) + print("ERROR: result type unknown " + b[1]) return 1 data = { 'revision_number': revision, - 'revision_project': proj, + 'revision_project': project, 'interpreter_name': interpreter, 'interpreter_coptions': int_options, 'benchmark_name': bench_name, @@ -49,8 +36,10 @@ 'result_value': value, 'result_date': current_date, } - send(data) - return 0 + if testing: testparams.append(data) + else: send(data) + if testing: return testparams + else: return 0 def send(data): #save results @@ -59,7 +48,7 @@ response = "None" info = str(datetime.today()) + ": Saving result for " + data['interpreter_name'] + " revision " info += str(data['revision_number']) + ", benchmark " + data['benchmark_name'] - logger.info(info) + print(info) try: f = urllib2.urlopen(SPEEDURL + 'result/add/', params) response = f.read() @@ -71,5 +60,5 @@ elif hasattr(e, 'code'): response = '\n The server couldn\'t fulfill the request\n' response += ' Error code: ' + str(e) - logger.critical("Server (%s) response: %s\n" % (SPEEDURL, response)) + print("Server (%s) response: %s\n" % (SPEEDURL, response)) return 1 Added: codespeed/tools/test_saveresults.py ============================================================================== --- (empty file) +++ codespeed/tools/test_saveresults.py Mon Mar 1 10:48:36 2010 @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +import saveresults +import unittest + +class testSaveresults(unittest.TestCase): + '''Tests Saveresults script for saving data to speed.pypy.org''' + fixture = [ + ['ai', 'ComparisonResult', {'avg_base': 0.42950453758219992, 'timeline_link': None, 'avg_changed': 0.43322672843939997, 'min_base': 0.42631793022199999, 'delta_min': '1.0065x faster', 'delta_avg': '1.0087x slower', 'std_changed': 0.0094009621054567376, 'min_changed': 0.423564910889, 'delta_std': '2.7513x larger', 'std_base': 0.0034169249420902843, 't_msg': 'Not significant\n'}], + ['chaos', 'ComparisonResult', {'avg_base': 0.41804099082939999, 'timeline_link': None, 'avg_changed': 0.11744904518135998, 'min_base': 0.41700506210299998, 'delta_min': '9.0148x faster', 'delta_avg': '3.5593x faster', 'std_changed': 0.14350186143481433, 'min_changed': 0.046257972717299999, 'delta_std': '108.8162x larger', 'std_base': 0.0013187546718754512, 't_msg': 'Significant (t=4.683672, a=0.95)\n'}], + ['django', 'ComparisonResult', {'avg_base': 0.83651852607739996, 'timeline_link': None, 'avg_changed': 0.48571481704719999, 'min_base': 0.82990884780899998, 'delta_min': '1.7315x faster', 'delta_avg': '1.7222x faster', 'std_changed': 0.006386606999421761, 'min_changed': 0.47929787635799997, 'delta_std': '1.7229x smaller', 'std_base': 0.011003382690633789, 't_msg': 'Significant (t=61.655971, a=0.95)\n'}], + ['fannkuch', 'ComparisonResult', {'avg_base': 1.8561528205879998, 'timeline_link': None, 'avg_changed': 0.38401727676399999, 'min_base': 1.84801197052, 'delta_min': '5.0064x faster', 'delta_avg': '4.8335x faster', 'std_changed': 0.029594360755246251, 'min_changed': 0.36913013458299998, 'delta_std': '3.2353x larger', 'std_base': 0.0091472519207758066, 't_msg': 'Significant (t=106.269998, a=0.95)\n'}], + ['float', 'ComparisonResult', {'avg_base': 0.50523018836940004, 'timeline_link': None, 'avg_changed': 0.15490598678593998, 'min_base': 0.49911379814099999, 'delta_min': '6.2651x faster', 'delta_avg': '3.2615x faster', 'std_changed': 0.057739598339608837, 'min_changed': 0.079665899276699995, 'delta_std': '7.7119x larger', 'std_base': 0.007487037523761327, 't_msg': 'Significant (t=13.454285, a=0.95)\n'}], ['gcbench', 'SimpleComparisonResult', {'base_time': 27.236408948899999, 'changed_time': 5.3500790595999996, 'time_delta': '5.0908x faster'}], + ['html5lib', 'SimpleComparisonResult', {'base_time': 11.666918992999999, 'changed_time': 12.6703209877, 'time_delta': '1.0860x slower'}], + ['richards', 'ComparisonResult', {'avg_base': 0.29083266258220003, 'timeline_link': None, 'avg_changed': 0.029299402236939998, 'min_base': 0.29025602340700002, 'delta_min': '10.7327x faster', 'delta_avg': '9.9262x faster', 'std_changed': 0.0033452973342946888, 'min_changed': 0.027044057846099999, 'delta_std': '5.6668x larger', 'std_base': 0.00059033067516221327, 't_msg': 'Significant (t=172.154488, a=0.95)\n'}], + ['rietveld', 'ComparisonResult', {'avg_base': 0.46909418106079998, 'timeline_link': None, 'avg_changed': 1.312631273269, 'min_base': 0.46490097045899997, 'delta_min': '2.1137x slower', 'delta_avg': '2.7982x slower', 'std_changed': 0.44401595627955542, 'min_changed': 0.98267102241500004, 'delta_std': '76.0238x larger', 'std_base': 0.0058404831974135556, 't_msg': 'Significant (t=-4.247692, a=0.95)\n'}], + ['slowspitfire', 'ComparisonResult', {'avg_base': 0.66740002632140005, 'timeline_link': None, 'avg_changed': 1.6204295635219998, 'min_base': 0.65965509414699997, 'delta_min': '1.9126x slower', 'delta_avg': '2.4280x slower', 'std_changed': 0.27415559151786589, 'min_changed': 1.26167798042, 'delta_std': '20.1860x larger', 'std_base': 0.013581457669479846, 't_msg': 'Significant (t=-7.763579, a=0.95)\n'}], + ['spambayes', 'ComparisonResult', {'avg_base': 0.279049730301, 'timeline_link': None, 'avg_changed': 1.0178018569945999, 'min_base': 0.27623891830399999, 'delta_min': '3.3032x slower', 'delta_avg': '3.6474x slower', 'std_changed': 0.064953583956645466, 'min_changed': 0.91246294975300002, 'delta_std': '28.9417x larger', 'std_base': 0.0022442880892229711, 't_msg': 'Significant (t=-25.416839, a=0.95)\n'}], + ['spectral-norm', 'ComparisonResult', {'avg_base': 0.48315834999099999, 'timeline_link': None, 'avg_changed': 0.066225481033300004, 'min_base': 0.476922035217, 'delta_min': '8.0344x faster', 'delta_avg': '7.2957x faster', 'std_changed': 0.013425108838933627, 'min_changed': 0.059360027313200003, 'delta_std': '1.9393x larger', 'std_base': 0.0069225510731835901, 't_msg': 'Significant (t=61.721418, a=0.95)\n'}], + ['spitfire', 'ComparisonResult', {'avg_base': 7.1179999999999994, 'timeline_link': None, 'avg_changed': 7.2780000000000005, 'min_base': 7.04, 'delta_min': '1.0072x faster', 'delta_avg': '1.0225x slower', 'std_changed': 0.30507376157250898, 'min_changed': 6.9900000000000002, 'delta_std': '3.4948x larger', 'std_base': 0.08729261137118062, 't_msg': 'Not significant\n'}], + ['twisted_iteration', 'SimpleComparisonResult', {'base_time': 0.148289627437, 'changed_time': 0.035354803126799998, 'time_delta': '4.1943x faster'}], + ['twisted_web', 'SimpleComparisonResult', {'base_time': 0.11312217194599999, 'changed_time': 0.625, 'time_delta': '5.5250x slower'}] + ] + + def testGoodInput(self): + '''Given correct result data, check that every result being saved has the right parameters''' + for resultparams in saveresults.save("pypy", 71212, self.fixture, "", "trunk", "pypy-c-jit", "gc=hybrid", True): + self.assertEqual(resultparams['revision_project'], "pypy") + self.assertEqual(resultparams['revision_number'], 71212) + self.assertEqual(resultparams['interpreter_name'], "pypy-c-jit") + self.assertEqual(resultparams['interpreter_coptions'], "gc=hybrid") + # get dict with correct data for this benchmark + fixturedata = [] + benchfound = False + for res in self.fixture: + if res[0] == resultparams['benchmark_name']: + fixturedata = res + benchfound = True + break + self.assertTrue(benchfound) + # get correct result value depending on the type of result + fixturevalue = 0 + if fixturedata[1] == "SimpleComparisonResult": + fixturevalue = fixturedata[2]['changed_time'] + else: + fixturevalue = fixturedata[2]['avg_changed'] + self.assertEqual(resultparams['result_value'], fixturevalue) + +if __name__ == "__main__": + unittest.main() From getxsick at codespeak.net Mon Mar 1 12:43:47 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 1 Mar 2010 12:43:47 +0100 (CET) Subject: [pypy-svn] r71589 - pypy/build/ubuntu Message-ID: <20100301114347.08F0D51054@codespeak.net> Author: getxsick Date: Mon Mar 1 12:43:45 2010 New Revision: 71589 Added: pypy/build/ubuntu/ - copied from r71588, pypy/build/debian/ Log: init ubuntu's package directory From arigo at codespeak.net Mon Mar 1 13:10:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 1 Mar 2010 13:10:19 +0100 (CET) Subject: [pypy-svn] r71590 - in pypy/trunk/pypy: jit/backend/x86/test jit/metainterp rpython rpython/lltypesystem Message-ID: <20100301121019.3D2DB51054@codespeak.net> Author: arigo Date: Mon Mar 1 13:10:18 2010 New Revision: 71590 Modified: pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py pypy/trunk/pypy/jit/metainterp/virtualref.py pypy/trunk/pypy/rpython/lltypesystem/rclass.py pypy/trunk/pypy/rpython/rtyper.py Log: Test and fix for --gcremovetypeptr together with the JIT. Modified: pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py Mon Mar 1 13:10:18 2010 @@ -439,3 +439,19 @@ def test_compile_hybrid_bug1(self): self.run('compile_hybrid_bug1', 200) + + def define_compile_hybrid_vref(self): + from pypy.rlib.jit import virtual_ref, virtual_ref_finish + class A: + pass + glob = A() + def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s): + a = A() + glob.v = virtual_ref(a) + virtual_ref_finish(a) + n -= 1 + return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s + return None, f, None + + def test_compile_hybrid_vref(self): + self.run('compile_hybrid_vref', 200) Modified: pypy/trunk/pypy/jit/metainterp/virtualref.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/virtualref.py (original) +++ pypy/trunk/pypy/jit/metainterp/virtualref.py Mon Mar 1 13:10:18 2010 @@ -27,6 +27,10 @@ self.descr_virtualref_index = fielddescrof(self.JIT_VIRTUAL_REF, 'virtualref_index') self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced') + # + # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too + self.warmrunnerdesc.rtyper.set_type_for_typeptr( + self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) def _freeze_(self): return True @@ -50,10 +54,6 @@ if c_funcptr is not None: log("replaced %d 'jit_force_virtual' with %r" % (count, c_funcptr.value)) - # - # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too - self.warmrunnerdesc.rtyper.set_type_for_typeptr( - self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) # ____________________________________________________________ Modified: pypy/trunk/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rclass.py Mon Mar 1 13:10:18 2010 @@ -384,7 +384,6 @@ OBJECT, destrptr) vtable = self.rclass.getvtable() self.rtyper.set_type_for_typeptr(vtable, self.lowleveltype.TO) - self.rtyper.lltype2vtable[self.lowleveltype.TO] = vtable def common_repr(self): # -> object or nongcobject reprs return getinstancerepr(self.rtyper, None, self.gcflavor) Modified: pypy/trunk/pypy/rpython/rtyper.py ============================================================================== --- pypy/trunk/pypy/rpython/rtyper.py (original) +++ pypy/trunk/pypy/rpython/rtyper.py Mon Mar 1 13:10:18 2010 @@ -152,6 +152,7 @@ def set_type_for_typeptr(self, typeptr, TYPE): self.type_for_typeptr[typeptr._obj] = TYPE + self.lltype2vtable[TYPE] = typeptr def get_real_typeptr_for_typeptr(self, typeptr): # perform a linear scan for the case of ll2ctypes typeptr From getxsick at codespeak.net Tue Mar 2 00:15:59 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 00:15:59 +0100 (CET) Subject: [pypy-svn] r71595 - pypy/build/ubuntu/debian Message-ID: <20100301231559.D1C0651055@codespeak.net> Author: getxsick Date: Tue Mar 2 00:15:58 2010 New Revision: 71595 Modified: pypy/build/ubuntu/debian/rules Log: fix unsafe usage of quilt Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 2 00:15:58 2010 @@ -24,7 +24,7 @@ Makefile: debian/Makefile.in python debian/configure.py --build=$(DEB_BUILD_ARCH) --host=$(DEB_HOST_ARCH) --prefix=debian/tmp/usr debian/Makefile.in -build: patch build-arch build-indep +build: ${QUILT_STAMPFN} build-arch build-indep build-arch: build-arch-stamp build-arch-stamp: Makefile From getxsick at codespeak.net Tue Mar 2 00:21:08 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 00:21:08 +0100 (CET) Subject: [pypy-svn] r71596 - pypy/build/ubuntu/debian Message-ID: <20100301232108.C62A251055@codespeak.net> Author: getxsick Date: Tue Mar 2 00:21:07 2010 New Revision: 71596 Modified: pypy/build/ubuntu/debian/rules Log: switch curly brackets to round ones (both work, just to keep the standard) Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 2 00:21:07 2010 @@ -24,7 +24,7 @@ Makefile: debian/Makefile.in python debian/configure.py --build=$(DEB_BUILD_ARCH) --host=$(DEB_HOST_ARCH) --prefix=debian/tmp/usr debian/Makefile.in -build: ${QUILT_STAMPFN} build-arch build-indep +build: $(QUILT_STAMPFN) build-arch build-indep build-arch: build-arch-stamp build-arch-stamp: Makefile From getxsick at codespeak.net Tue Mar 2 00:34:55 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 00:34:55 +0100 (CET) Subject: [pypy-svn] r71597 - pypy/build/ubuntu/debian/patches Message-ID: <20100301233455.BB2E851055@codespeak.net> Author: getxsick Date: Tue Mar 2 00:34:53 2010 New Revision: 71597 Removed: pypy/build/ubuntu/debian/patches/02-mips-support Modified: pypy/build/ubuntu/debian/patches/series Log: remove unncessary patch (it's already implemented in the core) Modified: pypy/build/ubuntu/debian/patches/series ============================================================================== --- pypy/build/ubuntu/debian/patches/series (original) +++ pypy/build/ubuntu/debian/patches/series Tue Mar 2 00:34:53 2010 @@ -1,2 +1 @@ 01-package-specific-temp-prefix -02-mips-support From getxsick at codespeak.net Tue Mar 2 01:13:35 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 01:13:35 +0100 (CET) Subject: [pypy-svn] r71599 - pypy/build/ubuntu/debian/patches Message-ID: <20100302001335.71E3951055@codespeak.net> Author: getxsick Date: Tue Mar 2 01:13:33 2010 New Revision: 71599 Removed: pypy/build/ubuntu/debian/patches/ Log: remove unnecessary patch (improper bugfix for #452851 at Debian Bug). From getxsick at codespeak.net Tue Mar 2 01:14:23 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 01:14:23 +0100 (CET) Subject: [pypy-svn] r71600 - pypy/build/ubuntu/debian Message-ID: <20100302001423.D694251055@codespeak.net> Author: getxsick Date: Tue Mar 2 01:14:22 2010 New Revision: 71600 Modified: pypy/build/ubuntu/debian/control pypy/build/ubuntu/debian/rules Log: remove quilt as there is no patches anymore Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Tue Mar 2 01:14:22 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Chris Lamb -Build-Depends: debhelper (>= 6), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, quilt +Build-Depends: debhelper (>= 6), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev Standards-Version: 3.7.3 Vcs-Git: git://git.chris-lamb.co.uk/pkg-pypy.git Vcs-Browser: http://git.chris-lamb.co.uk/?p=pkg-pypy.git Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 2 01:14:22 2010 @@ -3,8 +3,6 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -include /usr/share/quilt/quilt.make - # This has to be exported to make some magic below work. export DH_OPTIONS @@ -24,7 +22,7 @@ Makefile: debian/Makefile.in python debian/configure.py --build=$(DEB_BUILD_ARCH) --host=$(DEB_HOST_ARCH) --prefix=debian/tmp/usr debian/Makefile.in -build: $(QUILT_STAMPFN) build-arch build-indep +build: build-arch build-indep build-arch: build-arch-stamp build-arch-stamp: Makefile @@ -35,7 +33,7 @@ build-indep-stamp: touch $@ -clean: unpatch +clean: dh_testdir dh_testroot rm -f build-arch-stamp build-indep-stamp @@ -123,4 +121,4 @@ $(MAKE) -f debian/rules DH_OPTIONS=-s binary-common binary: binary-arch binary-indep -.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch patch unpatch get-orig-source +.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch get-orig-source From agaynor at codespeak.net Tue Mar 2 04:50:50 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Tue, 2 Mar 2010 04:50:50 +0100 (CET) Subject: [pypy-svn] r71604 - in pypy/trunk/pypy: doc objspace/std objspace/std/test Message-ID: <20100302035050.E4C3D51055@codespeak.net> Author: agaynor Date: Tue Mar 2 04:50:41 2010 New Revision: 71604 Modified: pypy/trunk/pypy/doc/objspace.txt pypy/trunk/pypy/objspace/std/floatobject.py pypy/trunk/pypy/objspace/std/intobject.py pypy/trunk/pypy/objspace/std/longobject.py pypy/trunk/pypy/objspace/std/multimethod.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/smallintobject.py pypy/trunk/pypy/objspace/std/stdtypedef.py pypy/trunk/pypy/objspace/std/test/test_intobject.py Log: #480. FailedToImplement is now split into FailedToImplement and FailedToImplementArgs which has w_type and w_value. Modified: pypy/trunk/pypy/doc/objspace.txt ============================================================================== --- pypy/trunk/pypy/doc/objspace.txt (original) +++ pypy/trunk/pypy/doc/objspace.txt Tue Mar 2 04:50:41 2010 @@ -316,7 +316,7 @@ try: z = ovfcheck(x + y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer addition")) return W_IntObject(space, z) Modified: pypy/trunk/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/floatobject.py Tue Mar 2 04:50:41 2010 @@ -241,7 +241,7 @@ x = w_float1.floatval y = w_float2.floatval if y == 0.0: - raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float division")) + raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division")) return W_FloatObject(x / y) truediv__Float_Float = div__Float_Float @@ -254,7 +254,7 @@ x = w_float1.floatval y = w_float2.floatval if y == 0.0: - raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float modulo")) + raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo")) mod = math.fmod(x, y) if (mod and ((y < 0.0) != (mod < 0.0))): mod += y @@ -265,7 +265,7 @@ x = w_float1.floatval y = w_float2.floatval if y == 0.0: - raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float modulo")) + raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float modulo")) mod = math.fmod(x, y) # fmod is typically exact, so vx-mod is *mathematically* an # exact multiple of wx. But this is fp arithmetic, and fp @@ -338,9 +338,9 @@ try: z = math.pow(x,y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, space.wrap("float power")) + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("float power")) except ValueError: - raise FailedToImplement(space.w_ValueError, space.wrap("float power")) # xxx + raise FailedToImplementArgs(space.w_ValueError, space.wrap("float power")) # xxx return W_FloatObject(z) Modified: pypy/trunk/pypy/objspace/std/intobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/intobject.py (original) +++ pypy/trunk/pypy/objspace/std/intobject.py Tue Mar 2 04:50:41 2010 @@ -86,7 +86,7 @@ try: z = ovfcheck(x + y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer addition")) return wrapint(space, z) @@ -96,7 +96,7 @@ try: z = ovfcheck(x - y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer substraction")) return wrapint(space, z) @@ -106,7 +106,7 @@ try: z = ovfcheck(x * y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer multiplication")) return wrapint(space, z) @@ -119,7 +119,7 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("integer division by zero")) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer division")) return wrapint(space, z) div__Int_Int = floordiv__Int_Int @@ -128,7 +128,7 @@ x = float(w_int1.intval) y = float(w_int2.intval) if y == 0.0: - raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float division")) + raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division")) return space.wrap(x / y) def mod__Int_Int(space, w_int1, w_int2): @@ -140,7 +140,7 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("integer modulo by zero")) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer modulo")) return wrapint(space, z) @@ -153,7 +153,7 @@ raise OperationError(space.w_ZeroDivisionError, space.wrap("integer divmod by zero")) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer modulo")) # no overflow possible m = x % y @@ -169,7 +169,7 @@ space.wrap("pow() 2nd argument " "cannot be negative when 3rd argument specified")) ## bounce it, since it always returns float - raise FailedToImplement(space.w_ValueError, + raise FailedToImplementArgs(space.w_ValueError, space.wrap("integer exponentiation")) temp = iv ix = 1 @@ -188,7 +188,7 @@ if iz: ix = ix % iz except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer exponentiation")) return wrapint(space, ix) @@ -211,7 +211,7 @@ try: x = ovfcheck(-a) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer negation")) return wrapint(space, x) @@ -239,12 +239,12 @@ if a == 0 or b == 0: return int__Int(space, w_int1) if b >= LONG_BIT: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) try: c = ovfcheck_lshift(a, b) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) return wrapint(space, c) Modified: pypy/trunk/pypy/objspace/std/longobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/longobject.py (original) +++ pypy/trunk/pypy/objspace/std/longobject.py Tue Mar 2 04:50:41 2010 @@ -195,7 +195,7 @@ def pow__Long_Long_None(space, w_long1, w_long2, w_long3): # XXX need to replicate some of the logic, to get the errors right if w_long2.num.lt(rbigint.fromint(0)): - raise FailedToImplement( + raise FailedToImplementArgs( space.w_ValueError, space.wrap("long pow() too negative")) return W_LongObject(w_long1.num.pow(w_long2.num, None)) Modified: pypy/trunk/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/trunk/pypy/objspace/std/multimethod.py (original) +++ pypy/trunk/pypy/objspace/std/multimethod.py Tue Mar 2 04:50:41 2010 @@ -25,6 +25,20 @@ class FailedToImplement(Exception): + def __init__(self, *args): + if args: + raise Exception + + def get_w_value(self, space): + return None + + def get_w_type(self, space): + return None + + def __str__(self): + return '' + +class FailedToImplementArgs(FailedToImplement): def __init__(self, w_type=None, w_value=None): self.w_type = w_type self.w_value = w_value @@ -32,9 +46,13 @@ def get_w_value(self, space): # convenience: same semantics as with OperationError return self.w_value + + def get_w_type(self, space): + return self.w_type def __str__(self): return '' % (self.w_type, self.w_value) + def raiseFailedToImplement(): Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Mar 2 04:50:41 2010 @@ -13,7 +13,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.objspace.std.model import W_Object, UnwrapError from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel -from pypy.objspace.std.multimethod import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.objspace.std import stdtypedef from pypy.rlib.rarithmetic import base_int Modified: pypy/trunk/pypy/objspace/std/smallintobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/smallintobject.py (original) +++ pypy/trunk/pypy/objspace/std/smallintobject.py Tue Mar 2 04:50:41 2010 @@ -91,7 +91,7 @@ try: z = ovfcheck(x * y) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer multiplication")) return wrapint(space, z) @@ -110,7 +110,7 @@ x = float(w_int1.intval) y = float(w_int2.intval) if y == 0.0: - raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float division")) + raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division")) return space.wrap(x / y) def mod__SmallInt_SmallInt(space, w_int1, w_int2): @@ -178,12 +178,12 @@ if a == 0 or b == 0: return int__SmallInt(space, w_int1) if b >= LONG_BIT: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) try: c = ovfcheck_lshift(a, b) except OverflowError: - raise FailedToImplement(space.w_OverflowError, + raise FailedToImplementArgs(space.w_OverflowError, space.wrap("integer left shift")) return wrapint(space, c) Modified: pypy/trunk/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/pypy/objspace/std/stdtypedef.py Tue Mar 2 04:50:41 2010 @@ -219,7 +219,7 @@ try: return %s except FailedToImplement, e: - if e.w_type is not None: + if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: return space.w_NotImplemented @@ -231,7 +231,7 @@ try: w_res = %s except FailedToImplement, e: - if e.w_type is not None: + if e.get_w_type(space) is not None: raise OperationError(e.w_type, e.get_w_value(space)) else: raise gettypeerror(space, %r, %s) Modified: pypy/trunk/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_intobject.py Tue Mar 2 04:50:41 2010 @@ -25,7 +25,7 @@ res = func(*args, **kwds) raise Exception, "should have failed but returned '%s'!" %repr(res) except FailedToImplement, arg: - return arg.w_type + return arg.get_w_type(self.space) def test_int_w(self): assert self.space.int_w(self.space.wrap(42)) == 42 From agaynor at codespeak.net Tue Mar 2 04:53:27 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Tue, 2 Mar 2010 04:53:27 +0100 (CET) Subject: [pypy-svn] r71605 - pypy/trunk/pypy/objspace/std Message-ID: <20100302035327.6FABA51055@codespeak.net> Author: agaynor Date: Tue Mar 2 04:53:25 2010 New Revision: 71605 Modified: pypy/trunk/pypy/objspace/std/multimethod.py Log: Remove a debugging bit from the previous commit. Modified: pypy/trunk/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/trunk/pypy/objspace/std/multimethod.py (original) +++ pypy/trunk/pypy/objspace/std/multimethod.py Tue Mar 2 04:53:25 2010 @@ -25,10 +25,6 @@ class FailedToImplement(Exception): - def __init__(self, *args): - if args: - raise Exception - def get_w_value(self, space): return None From fijal at codespeak.net Tue Mar 2 05:26:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 05:26:07 +0100 (CET) Subject: [pypy-svn] r71606 - pypy/branch/readwrite-experiments Message-ID: <20100302042607.7A2CC51055@codespeak.net> Author: fijal Date: Tue Mar 2 05:26:05 2010 New Revision: 71606 Removed: pypy/branch/readwrite-experiments/ Log: Branch got nowhere, delete From fijal at codespeak.net Tue Mar 2 05:45:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 05:45:36 +0100 (CET) Subject: [pypy-svn] r71607 - in pypy/trunk/pypy: . tool tool/pytest translator/platform Message-ID: <20100302044536.6A57351055@codespeak.net> Author: fijal Date: Tue Mar 2 05:45:34 2010 New Revision: 71607 Modified: pypy/trunk/pypy/conftest.py pypy/trunk/pypy/tool/ansi_mandelbrot.py pypy/trunk/pypy/tool/ansi_print.py pypy/trunk/pypy/tool/pytest/appsupport.py pypy/trunk/pypy/translator/platform/__init__.py Log: Make pypy work with py.test 1.2.1 (last release). It does not work completely, because of sys.path issues, but at least you can set PYTHONPATH and it works. Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Tue Mar 2 05:45:34 2010 @@ -1,5 +1,8 @@ import py, sys, os -from py.impl.test.outcome import Failed +try: + from py.impl.test.outcome import Failed +except: + from py._test.outcome import Failed from pypy.interpreter.gateway import app2interp_temp from pypy.interpreter.error import OperationError from pypy.tool.pytest import appsupport Modified: pypy/trunk/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/trunk/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/trunk/pypy/tool/ansi_mandelbrot.py Tue Mar 2 05:45:34 2010 @@ -1,6 +1,9 @@ import sys -from py.impl.io.terminalwriter import ansi_print, get_terminal_width +try: + from py.impl.io.terminalwriter import ansi_print, get_terminal_width +except: + from py._io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/trunk/pypy/tool/ansi_print.py ============================================================================== --- pypy/trunk/pypy/tool/ansi_print.py (original) +++ pypy/trunk/pypy/tool/ansi_print.py Tue Mar 2 05:45:34 2010 @@ -4,7 +4,10 @@ import sys -from py.impl.io.terminalwriter import ansi_print +try: + from py.impl.io.terminalwriter import ansi_print +except: + from py._io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/trunk/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/appsupport.py (original) +++ pypy/trunk/pypy/tool/pytest/appsupport.py Tue Mar 2 05:45:34 2010 @@ -1,10 +1,15 @@ import autopath import py -import py.impl.code.assertion -from py.impl.code import _assertionold as exprinfo +try: + import py.impl.code.assertion + from py.impl.code import _assertionold as exprinfo + from py.impl.test.outcome import ExceptionFailure +except: + import py._code.assertion + from py._code import _assertionold as exprinfo + from py._test.outcome import ExceptionFailure from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from py.impl.test.outcome import ExceptionFailure # ____________________________________________________________ Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Tue Mar 2 05:45:34 2010 @@ -6,7 +6,10 @@ import sys, py, os from pypy.tool.ansi_print import ansi_log -from py.impl.code.code import safe_repr +try: + from py.impl.code.code import safe_repr +except: + from py._code.code import safe_repr log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) From fijal at codespeak.net Tue Mar 2 05:47:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 05:47:53 +0100 (CET) Subject: [pypy-svn] r71608 - in pypy/branch/jit-sandbox/pypy: . tool tool/pytest translator/platform Message-ID: <20100302044753.0A60751055@codespeak.net> Author: fijal Date: Tue Mar 2 05:47:52 2010 New Revision: 71608 Modified: pypy/branch/jit-sandbox/pypy/conftest.py pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py pypy/branch/jit-sandbox/pypy/tool/ansi_print.py pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py Log: Merge 71607 from trunk Modified: pypy/branch/jit-sandbox/pypy/conftest.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/conftest.py (original) +++ pypy/branch/jit-sandbox/pypy/conftest.py Tue Mar 2 05:47:52 2010 @@ -1,5 +1,8 @@ import py, sys, os -from py.impl.test.outcome import Failed +try: + from py.impl.test.outcome import Failed +except: + from py._test.outcome import Failed from pypy.interpreter.gateway import app2interp_temp from pypy.interpreter.error import OperationError from pypy.tool.pytest import appsupport Modified: pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py Tue Mar 2 05:47:52 2010 @@ -1,6 +1,9 @@ import sys -from py.impl.io.terminalwriter import ansi_print, get_terminal_width +try: + from py.impl.io.terminalwriter import ansi_print, get_terminal_width +except: + from py._io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/branch/jit-sandbox/pypy/tool/ansi_print.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/ansi_print.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/ansi_print.py Tue Mar 2 05:47:52 2010 @@ -4,7 +4,10 @@ import sys -from py.impl.io.terminalwriter import ansi_print +try: + from py.impl.io.terminalwriter import ansi_print +except: + from py._io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py Tue Mar 2 05:47:52 2010 @@ -1,10 +1,15 @@ import autopath import py -import py.impl.code.assertion -from py.impl.code import _assertionold as exprinfo +try: + import py.impl.code.assertion + from py.impl.code import _assertionold as exprinfo + from py.impl.test.outcome import ExceptionFailure +except: + import py._code.assertion + from py._code import _assertionold as exprinfo + from py._test.outcome import ExceptionFailure from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from py.impl.test.outcome import ExceptionFailure # ____________________________________________________________ Modified: pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py Tue Mar 2 05:47:52 2010 @@ -6,7 +6,10 @@ import sys, py, os from pypy.tool.ansi_print import ansi_log -from py.impl.code.code import safe_repr +try: + from py.impl.code.code import safe_repr +except: + from py._code.code import safe_repr log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) From fijal at codespeak.net Tue Mar 2 05:51:27 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 05:51:27 +0100 (CET) Subject: [pypy-svn] r71609 - in pypy/trunk/pypy: . tool tool/pytest translator/platform Message-ID: <20100302045127.AFECB51055@codespeak.net> Author: fijal Date: Tue Mar 2 05:51:25 2010 New Revision: 71609 Modified: pypy/trunk/pypy/conftest.py pypy/trunk/pypy/tool/ansi_mandelbrot.py pypy/trunk/pypy/tool/ansi_print.py pypy/trunk/pypy/tool/pytest/appsupport.py pypy/trunk/pypy/translator/platform/__init__.py Log: Revert 71607. It seems I can't make recent py.test working with pypy anyway, since py.test introduced regressions and holger is on holiday. Modified: pypy/trunk/pypy/conftest.py ============================================================================== --- pypy/trunk/pypy/conftest.py (original) +++ pypy/trunk/pypy/conftest.py Tue Mar 2 05:51:25 2010 @@ -1,8 +1,5 @@ import py, sys, os -try: - from py.impl.test.outcome import Failed -except: - from py._test.outcome import Failed +from py.impl.test.outcome import Failed from pypy.interpreter.gateway import app2interp_temp from pypy.interpreter.error import OperationError from pypy.tool.pytest import appsupport Modified: pypy/trunk/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/trunk/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/trunk/pypy/tool/ansi_mandelbrot.py Tue Mar 2 05:51:25 2010 @@ -1,9 +1,6 @@ import sys -try: - from py.impl.io.terminalwriter import ansi_print, get_terminal_width -except: - from py._io.terminalwriter import ansi_print, get_terminal_width +from py.impl.io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/trunk/pypy/tool/ansi_print.py ============================================================================== --- pypy/trunk/pypy/tool/ansi_print.py (original) +++ pypy/trunk/pypy/tool/ansi_print.py Tue Mar 2 05:51:25 2010 @@ -4,10 +4,7 @@ import sys -try: - from py.impl.io.terminalwriter import ansi_print -except: - from py._io.terminalwriter import ansi_print +from py.impl.io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/trunk/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/trunk/pypy/tool/pytest/appsupport.py (original) +++ pypy/trunk/pypy/tool/pytest/appsupport.py Tue Mar 2 05:51:25 2010 @@ -1,15 +1,10 @@ import autopath import py -try: - import py.impl.code.assertion - from py.impl.code import _assertionold as exprinfo - from py.impl.test.outcome import ExceptionFailure -except: - import py._code.assertion - from py._code import _assertionold as exprinfo - from py._test.outcome import ExceptionFailure +import py.impl.code.assertion +from py.impl.code import _assertionold as exprinfo from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from py.impl.test.outcome import ExceptionFailure # ____________________________________________________________ Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Tue Mar 2 05:51:25 2010 @@ -6,10 +6,7 @@ import sys, py, os from pypy.tool.ansi_print import ansi_log -try: - from py.impl.code.code import safe_repr -except: - from py._code.code import safe_repr +from py.impl.code.code import safe_repr log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) From fijal at codespeak.net Tue Mar 2 05:53:28 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 05:53:28 +0100 (CET) Subject: [pypy-svn] r71610 - in pypy/branch/jit-sandbox/pypy: . tool tool/pytest translator/platform Message-ID: <20100302045328.5760551055@codespeak.net> Author: fijal Date: Tue Mar 2 05:53:26 2010 New Revision: 71610 Modified: pypy/branch/jit-sandbox/pypy/conftest.py pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py pypy/branch/jit-sandbox/pypy/tool/ansi_print.py pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py Log: Revert 71608 Modified: pypy/branch/jit-sandbox/pypy/conftest.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/conftest.py (original) +++ pypy/branch/jit-sandbox/pypy/conftest.py Tue Mar 2 05:53:26 2010 @@ -1,8 +1,5 @@ import py, sys, os -try: - from py.impl.test.outcome import Failed -except: - from py._test.outcome import Failed +from py.impl.test.outcome import Failed from pypy.interpreter.gateway import app2interp_temp from pypy.interpreter.error import OperationError from pypy.tool.pytest import appsupport Modified: pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/ansi_mandelbrot.py Tue Mar 2 05:53:26 2010 @@ -1,9 +1,6 @@ import sys -try: - from py.impl.io.terminalwriter import ansi_print, get_terminal_width -except: - from py._io.terminalwriter import ansi_print, get_terminal_width +from py.impl.io.terminalwriter import ansi_print, get_terminal_width """ Black 0;30 Dark Gray 1;30 Modified: pypy/branch/jit-sandbox/pypy/tool/ansi_print.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/ansi_print.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/ansi_print.py Tue Mar 2 05:53:26 2010 @@ -4,10 +4,7 @@ import sys -try: - from py.impl.io.terminalwriter import ansi_print -except: - from py._io.terminalwriter import ansi_print +from py.impl.io.terminalwriter import ansi_print from pypy.tool.ansi_mandelbrot import Driver class AnsiLog: Modified: pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py (original) +++ pypy/branch/jit-sandbox/pypy/tool/pytest/appsupport.py Tue Mar 2 05:53:26 2010 @@ -1,15 +1,10 @@ import autopath import py -try: - import py.impl.code.assertion - from py.impl.code import _assertionold as exprinfo - from py.impl.test.outcome import ExceptionFailure -except: - import py._code.assertion - from py._code import _assertionold as exprinfo - from py._test.outcome import ExceptionFailure +import py.impl.code.assertion +from py.impl.code import _assertionold as exprinfo from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from py.impl.test.outcome import ExceptionFailure # ____________________________________________________________ Modified: pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/platform/__init__.py Tue Mar 2 05:53:26 2010 @@ -6,10 +6,7 @@ import sys, py, os from pypy.tool.ansi_print import ansi_log -try: - from py.impl.code.code import safe_repr -except: - from py._code.code import safe_repr +from py.impl.code.code import safe_repr log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) From dan at codespeak.net Tue Mar 2 06:52:53 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Tue, 2 Mar 2010 06:52:53 +0100 (CET) Subject: [pypy-svn] r71611 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100302055253.1E47151055@codespeak.net> Author: dan Date: Tue Mar 2 06:52:52 2010 New Revision: 71611 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/array.py pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Log: Added DynamicType object implementing (somewhat) the functionality of NumPy's dtype objects, did a bit of housekeeping. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/array.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/array.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/array.py Tue Mar 2 06:52:52 2010 @@ -6,6 +6,9 @@ from pypy.module.micronumpy.dtype import iterable_type +from pypy.module.micronumpy.dtype import get_dtype +from pypy.module.micronumpy.dtype import retrieve_dtype #FIXME: ambiguous name? + class BaseNumArray(Wrappable): pass @@ -22,7 +25,6 @@ if e.match(space, space.w_TypeError): pass else: raise - def mul_operation(): def mul(x, y): return x * y return mul @@ -91,9 +93,9 @@ try: if len(shape) == 1: length = shape[0] - return sdresult(space, w_dtype)(space, length, w_dtype) + return sdresult(w_dtype.code)(space, length, w_dtype) else: - return mdresult(space, w_dtype)(space, shape, w_dtype) + return mdresult(w_dtype.code)(space, shape, w_dtype) except KeyError, e: raise OperationError(space.w_NotImplementedError, space.wrap("Haven't implemented generic array yet!")) @@ -102,7 +104,8 @@ w_buffer=NoneNotWrapped, w_offset=NoneNotWrapped, w_strides=NoneNotWrapped, order='C'): shape_w = unpack_shape(space, w_shape) - result = construct_array(space, shape_w, w_dtype) + dtype_w = get_dtype(space, w_dtype) + result = construct_array(space, shape_w, dtype_w) #TODO: load from buffer? return space.wrap(result) descr_new.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root, @@ -121,8 +124,10 @@ shape = infer_shape(space, w_values) if w_dtype is None: - w_dtype = iterable_type(space, w_values) - result = construct_array(space, shape, w_dtype) + dtype_w = retrieve_dtype(space, iterable_type(space, w_values)) + else: + dtype_w = get_dtype(space, w_dtype) + result = construct_array(space, shape, dtype_w) result.load_iterable(w_values) return space.wrap(result) array.unwrap_spec = [ObjSpace, W_Root, W_Root, @@ -131,6 +136,10 @@ def zeros(space, w_shape, w_dtype=NoneNotWrapped, order='C'): shape_w = unpack_shape(space, w_shape) - result = construct_array(space, shape_w, w_dtype) + if w_dtype is None: + dtype_w = retrieve_dtype(space, 'd') + else: + dtype_w = get_dtype(space, w_dtype) + result = construct_array(space, shape_w, dtype_w) return space.wrap(result) zeros.unwrap_spec = [ObjSpace, W_Root, W_Root, str] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Tue Mar 2 06:52:52 2010 @@ -1,4 +1,8 @@ -?from pypy.interpreter.error import OperationError +?from pypy.interpreter.baseobjspace import ObjSpace, W_Root, Wrappable +from pypy.interpreter.error import OperationError +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import interp2app + def unwrap_int(space, w_x): return space.int_w(w_x) def coerce_int(space, w_x): @@ -15,34 +19,108 @@ def coerce_float32(space, w_x): return unwrap_float32(space, space.float(w_x)) -def result_mapping(space, w_types): - types = { - (space.w_int, space.w_int): space.w_int, - (space.w_int, space.w_float): space.w_float, - (space.w_float, space.w_int): space.w_float, - (space.w_float, space.w_float): space.w_float - } - return types[w_types] +def typecode(space, w_type): + try: + assert isinstance(w_type, DynamicType) + return w_type.code + except AssertionError, e: pass + + try: + return space.str_w(w_type) + except OperationError, e: + typecode_mapping = { + space.w_int: 'i', + space.w_float: 'd', + } + try: + return typecode_mapping[w_type] + except IndexError, e: + raise OperationError(space.w_TypeError, + space.wrap("Can't understand type.")) + +result_types = { + ('i', 'i'): 'i', + ('i', 'd'): 'd', + ('d', 'i'): 'd', + ('d', 'd'): 'd', + } + +def result_mapping(space, types): + types = (typecode(space, types[0]), + typecode(space, types[1])) + return result_types[types] def iterable_type(space, w_xs): xs = space.fixedview(w_xs) - result_type = space.w_int + result_type = 'i' for i in range(len(xs)): try: - space.iter(xs[i]) + atype = iterable_type(space, xs[i]) except OperationError, e: if not e.match(space, space.w_TypeError): raise - atype = space.type(xs[i]) - else: - atype = iterable_type(space, xs[i]) - result_type = result_mapping(space, (result_type, atype)) + atype = typecode(space, space.type(xs[i])) + result_type = result_types[(result_type, atype)] return result_type -def create_factory(dict_filler): - result_factory = {} - def result(space, t): - if not result_factory: - result_factory.update(dict_filler(space)) +def create_factory(result_factory): + def factory(t): return result_factory[t] - return result + return factory + +class DynamicType(Wrappable): + def __init__(self, code, name, applevel_type): + self.code = code + self.name = name + self.applevel_type = applevel_type + + def descr_eq(self, space, w_x): + if space.abstract_isinstance_w(w_x, space.w_type): + return space.eq(self.applevel_type, w_x) #FIXME: correct comparison? + else: + try: + code = space.str_w(w_x) + if self.code == code: + return space.wrap(True) + elif self.name == code: + return space.wrap(True) + else: + return space.wrap(False) + except OperationError, e: + return space.wrap(False) + except TypeError, e: + return space.wrap(False) #FIXME: need to throw applevel type error + descr_eq.unwrap_spec = ['self', ObjSpace, W_Root] +DynamicType.typedef = TypeDef('dtype', + __eq__ = interp2app(DynamicType.descr_eq), + ) + +class DynamicTypes(object): + def __init__(self): + self.dtypes = {} + def verify_dtype_dict(self, space): + if not self.dtypes: + self.dtypes.update( + { + 'i': DynamicType('i', 'int32', space.w_int), + 'd': DynamicType('d', 'float64', space.w_float), + } + ) + + def retrieve_dtype(self, space, t): + self.verify_dtype_dict(space) + return self.dtypes[t] + + def get_dtype(self, space, w_type): + try: + t = space.str_w(w_type) + except OperationError, e: + if e.match(space, space.w_TypeError): + t = typecode(space, w_type) + else: + raise + return self.retrieve_dtype(space, t) + +dtypes = DynamicTypes() +get_dtype = dtypes.get_dtype +retrieve_dtype = dtypes.retrieve_dtype Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Tue Mar 2 06:52:52 2010 @@ -365,4 +365,4 @@ MultiDimIntArray = create_mdarray(int, unwrap_int, coerce_int) MultiDimFloatArray = create_mdarray(float, unwrap_float, coerce_float) -mdresult = create_factory(lambda space: {space.w_int: MultiDimIntArray, space.w_float: MultiDimFloatArray}) +mdresult = create_factory({'i': MultiDimIntArray, 'd': MultiDimFloatArray}) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Tue Mar 2 06:52:52 2010 @@ -10,15 +10,6 @@ from pypy.module.micronumpy.mdarray import mdresult -def result_type(space, w_types): - types = { - (space.w_int, space.w_int): space.w_int, - (space.w_int, space.w_float): space.w_float, - (space.w_float, space.w_int): space.w_float, - (space.w_float, space.w_float): space.w_float - } - return types[w_types] - def unpack_shape(space, w_shape): if space.is_true(space.isinstance(w_shape, space.w_int)): return [space.int_w(w_shape)] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Tue Mar 2 06:52:52 2010 @@ -1,5 +1,4 @@ ?from pypy.interpreter.baseobjspace import W_Root, Wrappable -from pypy.objspace.std.sliceobject import W_SliceObject from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.gateway import interp2app @@ -9,7 +8,6 @@ from pypy.module.micronumpy.array import base_typedef from pypy.module.micronumpy.array import \ mul_operation, div_operation, add_operation, sub_operation -from pypy.module.micronumpy.array import copy_operation from pypy.module.micronumpy.dtype import unwrap_int, coerce_int from pypy.module.micronumpy.dtype import unwrap_float, coerce_float @@ -19,63 +17,22 @@ from pypy.module.micronumpy.dtype import create_factory +from pypy.module.micronumpy.dtype import get_dtype +from pypy.module.micronumpy.dtype import retrieve_dtype #FIXME: ambiguously named? +from pypy.module.micronumpy.dtype import DynamicType + #TODO: merge unwrap_spec decorator # from pypy.interpreter.gateway import unwrap_spec - class BaseSingleDimArray(BaseNumArray): pass def descr_dtype(space, self): - return self.dtype + return space.wrap(self.dtype) def descr_shape(space, self): return space.newtuple([space.wrap(self.len())]) - - -MUL = mul_operation() -DIV = div_operation() -ADD = add_operation() -SUB = sub_operation() -COPY = copy_operation() - def create_sdarray(data_type, unwrap, coerce): - - def create_math_operation(f): - opname = f.__name__ - def math_operation(self, w_x): - space = self.space - try: - space.iter(w_x) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - result_t = result_mapping(space, - (space.type(w_x), self.dtype)) - op2 = coerce(space, w_x) - result = sdresult(space, result_t)(space, self.len(), result_t) - operation = result.__class__.client_scalar[opname] - else: - lop = space.int_w(space.len(w_x)) - if lop != self.len(): - raise OperationError(space.w_ValueError, - space.wrap("shape mismatch: objects cannot be" - " broadcast to the same shape")) - dtype = iterable_type(space, w_x) - result_t = result_mapping(space, (dtype, self.dtype)) - op2 = sdresult(space, dtype)(space, lop, dtype) - op2.load_iterable(w_x) - result = sdresult(space, result_t)(space, self.len(), result_t) - operation = result.__class__.client_fixedview[opname] - - operation(result, self, op2) - - w_result = space.wrap(result) - return w_result - math_operation.unwrap_spec = ['self', W_Root] - math_operation.__name__ = 'descr_'+opname - return math_operation - class SingleDimIterator(Wrappable): def __init__(self, space, array, i): self.space = space @@ -105,39 +62,78 @@ def create_client_math_operation(f): def scalar_operation(self, source, x): for i in range(len(source.storage)): - self.storage[i] = data_type(f(source.storage[i], x)) + self.storage[i] = f(source.storage[i], x) - def fixedview_operation(self, source1, source2): + def fixedview_operation(self, a, b): for i in range(self.len()): - self.storage[i] = \ - data_type(f(source1.storage[i], source2.storage[i])) + self.storage[i] = f(a.storage[i], b.storage[i]) return scalar_operation, fixedview_operation + def create_math_operation(f): + opname = f.__name__ + def math_operation(self, w_x): + space = self.space + try: + space.iter(w_x) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + result_t = result_mapping(space, + (space.type(w_x), self.dtype)) + x = coerce(space, w_x) + result = sdresult(result_t)(space, + self.len(), retrieve_dtype(space, result_t) + ) + client_scalar[opname](result, self, x) + else: + operand_length = space.int_w(space.len(w_x)) + if operand_length != self.len(): + raise OperationError(space.w_ValueError, + space.wrap("shape mismatch: objects cannot be" + " broadcast to the same shape")) + dtype_w = retrieve_dtype(space, iterable_type(space, w_x)) + result_t = result_mapping(space, (dtype_w, self.dtype)) + xs = sdresult(dtype_w.code)(space, operand_length, dtype_w) + xs.load_iterable(w_x) + result = sdresult(result_t)( + space, self.len(), retrieve_dtype(space, result_t) + ) + client_fixedview[opname](result, self, xs) + + return space.wrap(result) + math_operation.unwrap_spec = ['self', W_Root] + math_operation.__name__ = "%s_descr_%s" % (str(data_type), opname) + return math_operation + + client_scalar = {} + client_fixedview = {} + + mul = mul_operation() + client_scalar['mul'], client_fixedview['mul'] = \ + create_client_math_operation(mul) + div = div_operation() + client_scalar['div'], client_fixedview['div'] = \ + create_client_math_operation(div) + add = add_operation() + client_scalar['add'], client_fixedview['add'] = \ + create_client_math_operation(add) + sub = sub_operation() + client_scalar['sub'], client_fixedview['sub'] = \ + create_client_math_operation(sub) + class NumArray(BaseSingleDimArray): def __init__(self, space, length, dtype): self.shape = (length,) self.space = space - self.storage = make_sure_not_resized([data_type(0.0)] * length) + self.storage = [data_type(0.0)] * length + assert isinstance(dtype, DynamicType) self.dtype = dtype + make_sure_not_resized(self.storage) - - client_scalar = {} - client_fixedview = {} - - client_scalar['mul'], client_fixedview['mul'] = \ - create_client_math_operation(MUL) - client_scalar['div'], client_fixedview['div'] = \ - create_client_math_operation(DIV) - client_scalar['add'], client_fixedview['add'] = \ - create_client_math_operation(ADD) - client_scalar['sub'], client_fixedview['sub'] = \ - create_client_math_operation(SUB) - - - descr_mul = create_math_operation(MUL) - descr_div = create_math_operation(DIV) - descr_add = create_math_operation(ADD) - descr_sub = create_math_operation(SUB) + descr_mul = create_math_operation(mul) + descr_div = create_math_operation(div) + descr_add = create_math_operation(add) + descr_sub = create_math_operation(sub) def load_iterable(self, w_values): space = self.space @@ -161,9 +157,9 @@ def descr_getitem(self, w_index): space = self.space - if isinstance(w_index, W_SliceObject): + if space.is_true(space.isinstance(w_index, space.w_slice)): start, stop, step, slen = w_index.indices4(space, self.len()) - res = sdresult(space, self.dtype)(space, slen, self.dtype) + res = sdresult(self.dtype.code)(space, slen, self.dtype) if step == 1: res.storage[:] = self.storage[start:stop] else: @@ -186,7 +182,7 @@ def descr_setitem(self, w_index, w_value): space = self.space - if isinstance(w_index, W_SliceObject): + if space.is_true(space.isinstance(w_index, space.w_slice)): start, stop, step, slen = w_index.indices4(space, self.len()) try: space.iter(w_value) @@ -260,12 +256,15 @@ __div__ = interp2app(NumArray.descr_div), __add__ = interp2app(NumArray.descr_add), __sub__ = interp2app(NumArray.descr_sub), + __rmul__ = interp2app(NumArray.descr_mul), __rdiv__ = interp2app(NumArray.descr_div), __radd__ = interp2app(NumArray.descr_add), __rsub__ = interp2app(NumArray.descr_sub), + __getitem__ = interp2app(NumArray.descr_getitem), __setitem__ = interp2app(NumArray.descr_setitem), + __len__ = interp2app(NumArray.descr_len), __str__ = interp2app(NumArray.descr_str), __repr__ = interp2app(NumArray.descr_repr), @@ -282,4 +281,4 @@ Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32) GenericArray = None -sdresult = create_factory(lambda space: {space.w_int: IntArray, space.w_float: FloatArray}) +sdresult = create_factory({'i': IntArray, 'd': FloatArray}) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Tue Mar 2 06:52:52 2010 @@ -49,6 +49,17 @@ (float, float): float } + typecodes = {int: 'i', + float: 'd'} + + typestrings = {int: 'int32', + float: 'float64'} + + def test_type(dtype, expected_type): + assert dtype == expected_type + assert dtype == typecodes[expected_type] + assert dtype == typestrings[expected_type] + for operand_types, result_type in types.iteritems(): for operator in (mul, div, add, sub): a_type, b_type = operand_types @@ -56,16 +67,16 @@ b = array(xrange(1, self.length + 1), dtype=b_type) c = operator(a, b) - assert c.dtype == result_type + test_type(c.dtype, result_type) d = operator(b, a) - assert d.dtype == result_type + test_type(d.dtype, result_type) e = operator(a, b_type(self.value)) - assert e.dtype == result_type + test_type(e.dtype, result_type) f = operator(a_type(self.value), b) - assert f.dtype == result_type + test_type(f.dtype, result_type) def test_iter(self): from numpy import array Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ufunc.py Tue Mar 2 06:52:52 2010 @@ -3,6 +3,9 @@ from pypy.module.micronumpy.dtype import result_mapping from pypy.module.micronumpy.sdarray import sdresult from pypy.module.micronumpy.mdarray import mdresult, compute_pos + +from pypy.module.micronumpy.dtype import retrieve_dtype + from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError from pypy.rlib.debug import make_sure_not_resized @@ -15,7 +18,7 @@ raise OperationError(space.w_ValueError, space.wrap("minimum of arrays of different length")) dtype = result_mapping(space, (w_a.dtype, w_b.dtype)) - res = construct_array(space, w_a.shape, dtype) + res = construct_array(space, w_a.shape, retrieve_dtype(space, dtype)) for i in range(len(w_a.storage)): one = w_a.storage[i] two = w_b.storage[i] @@ -74,7 +77,7 @@ dtype = result_mapping(space, (w_a.dtype, w_b.dtype)) - res = construct_array(space, shape, dtype) + res = construct_array(space, shape, retrieve_dtype(space, dtype)) res.storage[:] = data return space.wrap(res) dot.unwrap_spec = [ObjSpace, W_Root, W_Root] From arigo at codespeak.net Tue Mar 2 11:14:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 11:14:11 +0100 (CET) Subject: [pypy-svn] r71615 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100302101411.DF2FD282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 11:14:10 2010 New Revision: 71615 Modified: pypy/trunk/pypy/jit/metainterp/virtualref.py Log: Oups. Fix tests. Modified: pypy/trunk/pypy/jit/metainterp/virtualref.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/virtualref.py (original) +++ pypy/trunk/pypy/jit/metainterp/virtualref.py Tue Mar 2 11:14:10 2010 @@ -29,8 +29,9 @@ self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced') # # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too - self.warmrunnerdesc.rtyper.set_type_for_typeptr( - self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) + if hasattr(self.warmrunnerdesc, 'rtyper'): # <-- for tests + self.warmrunnerdesc.rtyper.set_type_for_typeptr( + self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF) def _freeze_(self): return True From arigo at codespeak.net Tue Mar 2 11:31:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 11:31:38 +0100 (CET) Subject: [pypy-svn] r71616 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100302103138.83817282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 11:31:36 2010 New Revision: 71616 Modified: pypy/trunk/pypy/objspace/std/multimethod.py pypy/trunk/pypy/objspace/std/test/test_multimethod.py Log: Reintroduce this check, using __new__ to avoid it getting in the way of the translation. See comment in new test. Modified: pypy/trunk/pypy/objspace/std/multimethod.py ============================================================================== --- pypy/trunk/pypy/objspace/std/multimethod.py (original) +++ pypy/trunk/pypy/objspace/std/multimethod.py Tue Mar 2 11:31:36 2010 @@ -25,6 +25,11 @@ class FailedToImplement(Exception): + def __new__(cls, *args): + if cls is FailedToImplement: + assert not args, "use FailedToImplementArgs!" + return Exception.__new__(cls, *args) + def get_w_value(self, space): return None Modified: pypy/trunk/pypy/objspace/std/test/test_multimethod.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_multimethod.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_multimethod.py Tue Mar 2 11:31:36 2010 @@ -2,6 +2,7 @@ from pypy.objspace.std import multimethod from pypy.objspace.std.multimethod import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplementArgs class W_Root(object): @@ -27,6 +28,19 @@ return 'fine' +def test_failedtoimplement(): + f = FailedToImplement() + assert f.get_w_type("space") is None + assert f.get_w_value("space") is None + f = FailedToImplementArgs("ab", "cd") + assert f.get_w_type("space") == "ab" + assert f.get_w_value("space") == "cd" + # for testing it's good to get the following behavior: + raises(AssertionError, FailedToImplement, "ab", "cd") + # but the class FailedToImplement should have no __init__ for translation: + assert '__init__' not in FailedToImplement.__dict__ + + class TestMultiMethod1: Installer = multimethod.InstallerVersion1 From arigo at codespeak.net Tue Mar 2 12:54:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 12:54:39 +0100 (CET) Subject: [pypy-svn] r71617 - pypy/branch/gcremovetypeptr Message-ID: <20100302115439.85483282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 12:54:37 2010 New Revision: 71617 Added: pypy/branch/gcremovetypeptr/ - copied from r71616, pypy/trunk/ Log: Make a branch just for running the performance plots. From arigo at codespeak.net Tue Mar 2 12:55:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 12:55:16 +0100 (CET) Subject: [pypy-svn] r71618 - pypy/branch/gcremovetypeptr/pypy/config Message-ID: <20100302115516.18131282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 12:55:14 2010 New Revision: 71618 Modified: pypy/branch/gcremovetypeptr/pypy/config/translationoption.py Log: Change this to True. Modified: pypy/branch/gcremovetypeptr/pypy/config/translationoption.py ============================================================================== --- pypy/branch/gcremovetypeptr/pypy/config/translationoption.py (original) +++ pypy/branch/gcremovetypeptr/pypy/config/translationoption.py Tue Mar 2 12:55:14 2010 @@ -73,7 +73,7 @@ ("translation.gcremovetypeptr", False)], }), BoolOption("gcremovetypeptr", "Remove the typeptr from every object", - default=False, cmdline="--gcremovetypeptr"), + default=True, cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "asmgcc"], From tobami at codespeak.net Tue Mar 2 13:14:56 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Tue, 2 Mar 2010 13:14:56 +0100 (CET) Subject: [pypy-svn] r71619 - in codespeed/pyspeed: codespeed media/css templates Message-ID: <20100302121456.B2C9C51055@codespeak.net> Author: tobami Date: Tue Mar 2 13:14:54 2010 New Revision: 71619 Modified: codespeed/pyspeed/codespeed/views.py codespeed/pyspeed/media/css/main.css codespeed/pyspeed/templates/overview.html codespeed/pyspeed/templates/overview_table.html codespeed/pyspeed/templates/timeline.html Log: Overview: Added average row. Fixed nav tabs for IE. Small fixes. Modified: codespeed/pyspeed/codespeed/views.py ============================================================================== --- codespeed/pyspeed/codespeed/views.py (original) +++ codespeed/pyspeed/codespeed/views.py Tue Mar 2 13:14:54 2010 @@ -22,7 +22,11 @@ result_list = {} baseline = Interpreter.objects.get(id=1) - baselinerev = Revision.objects.get(tag="2.6.2") + baselinerev = lastbase = Revision.objects.filter( + tag__isnull=False + ).filter( + project='cpython' + ).order_by('-number')[0] if data["baseline"] == "true": result_list["baseline"] = Result.objects.get( interpreter=baseline, benchmark=data["benchmark"], revision=baselinerev @@ -54,19 +58,21 @@ # Configuration of default parameters baseline = Interpreter.objects.get(id=1) - lastbase = Revision.objects.filter( + lastbaserev = Revision.objects.filter( tag__isnull=False ).filter( project='cpython' ).order_by('-number')[0] - baselinetag = lastbase.tag + baselinetag = lastbaserev.tag + baselinerev = lastbaserev.number + defaultbaseline = True if data.has_key("baseline"): if data["baseline"] == "false": defaultbaseline = False defaulthost = 1 - defaultbenchmark = 1 + defaultbenchmark = 2 if data.has_key("benchmark"): try: defaultbenchmark = int(data["benchmark"]) @@ -83,15 +89,27 @@ lastrevisions = [50, 200, 1000] defaultlast = 200 - if data.has_key("lastrevisions"): - if data["lastrevisions"] in lastrevisions: - defaultlast = data["lastrevisions"] + if data.has_key("revisions"): + if int(data["revisions"]) in lastrevisions: + defaultlast = data["revisions"] # Information for template interpreters = Interpreter.objects.filter(name__startswith=settings.PROJECT_NAME) benchmarks = Benchmark.objects.all() hostlist = Environment.objects.all() - return render_to_response('timeline.html', locals()) + return render_to_response('timeline.html', { + 'defaultinterpreters': defaultinterpreters, + 'defaultbaseline': defaultbaseline, + 'baseline': baseline, + 'baselinetag': baselinetag, + 'defaultbenchmark': defaultbenchmark, + 'defaulthost': defaulthost, + 'lastrevisions': lastrevisions, + 'defaultlast': defaultlast, + 'interpreters': interpreters, + 'benchmarks': benchmarks, + 'hostlist': hostlist + }) def getoverviewtable(request): interpreter = int(request.GET["interpreter"]) @@ -103,7 +121,6 @@ lastrevision = lastrevisions[0].number changerevision = lastrevisions[1].number pastrevisions = lastrevisions[trendconfig-2:trendconfig+1] - print pastrevisions result_list = Result.objects.filter( revision__number=lastrevision ).filter( @@ -157,7 +174,7 @@ if average: average = average / averagecount trend = (result - average)*100/average - trend = "%.2f" % trend + #trend = "%.2f" % trend else: trend = "-" @@ -174,6 +191,16 @@ 'relative': relative }) + totals = {'result': 0, 'change': 0, 'trend': 0, 'relative': 0} + lengths = {'result': 0, 'change': 0, 'trend': 0, 'relative': 0} + for row in table_list: + for key in totals.keys(): + if type(row[key]) == float: + totals[key] += row[key] + lengths[key] += 1 + for tot in totals: + if lengths[tot]: totals[tot] = totals[tot]/lengths[tot] + return render_to_response('overview_table.html', locals()) def overview(request): Modified: codespeed/pyspeed/media/css/main.css ============================================================================== --- codespeed/pyspeed/media/css/main.css (original) +++ codespeed/pyspeed/media/css/main.css Tue Mar 2 13:14:54 2010 @@ -1,13 +1,14 @@ body { min-width: 960px; - margin: 0; padding: 0; background-color: #596A74; + margin: 0; padding: 0; + background-color: #596A74; background-image: url(/media/images/vgradient-s.png); background-repeat: repeat-x; } a:link, a:visited { text-decoration: none; } a:hover { text-decoration: underline; } -div#containter { width: 98%; margin-bottom: 1%; margin-left: auto; margin-right: auto; } +div#containter { width: 98%; margin-left: auto; margin-right: auto; } div#title { position: relative; @@ -24,11 +25,16 @@ div#wrapper { margin: 0; } div#nav ul { - display: inline; margin: 0; padding: 0; padding-left: 15.3em; font-family: Verdana, sans-serif; } -div#nav li { display: inline-block; list-style: none; } +div#nav li { + display: inline-block; + vertical-align: top; + list-style: none; + zoom: 1; /* IE7 (hasLayout)*/ + *display: inline; /* IE */ +} div#nav ul li a:link, div#nav ul li a:visited { display: block; @@ -157,8 +163,7 @@ text-align: center; } -table.tablesorter thead tr td{} -table.tablesorter thead tr th, table.tablesorter tfoot tr th { +table.tablesorter thead tr th { background-color: #9DADC6; border: 1px solid #CDCDCD; font-size: 8pt; @@ -170,6 +175,14 @@ background-position: center right; cursor: pointer; } +table.tablesorter tfoot tr td { + border: 2px solid #CDCDCD; + border-right: 1px solid #CDCDCD; + padding: 4px; + vertical-align: top; + text-align: right; +} +table.tablesorter tfoot tr td.text { text-align: left; } table.tablesorter tbody td { color: #3D3D3D; padding: 4px; @@ -194,7 +207,7 @@ table.tablesorter tbody td.text {text-align: left;} -table.tablesorter tbody td.bar { +table.tablesorter tbody td.bar, table.tablesorter tfoot tr td.bar { background-image: url(/media/images/gridline.png); background-repeat: repeat; background-position: left top; @@ -203,13 +216,16 @@ border: none; background-color:transparent; } + +table.tablesorter tfoot tr td.bar { border: 2px solid #CDCDCD; border-left: 1px solid #CDCDCD;}/*Firefox table border-collapse bug*/ + table.tablesorter tbody td.bar img { vertical-align: middle; margin: 5px 5px 5px 0; border: none; } -table.tablesorter tbody span { +table.tablesorter tbody span, table.tablesorter tfoot span { display: block; height: 1.45em; margin-top: 0.2em; @@ -218,8 +234,8 @@ overflow: hidden; } -table.tablesorter tbody tr td.status-red { background-color: #FF5640; } -table.tablesorter tbody tr td.status-green { background-color: #9FD54D; } +table.tablesorter tbody tr td.status-red, .status-red { background-color: #FF5640; } +table.tablesorter tbody tr td.status-green, .status-green { background-color: #9FD54D; } /* table.tablesorter tbody tr td.status-yellow { background-color: #FEE772; } */ table.tablesorter tbody tr.highlight td { background-color: #9DADC6 !important; Modified: codespeed/pyspeed/templates/overview.html ============================================================================== --- codespeed/pyspeed/templates/overview.html (original) +++ codespeed/pyspeed/templates/overview.html Tue Mar 2 13:14:54 2010 @@ -51,10 +51,20 @@ var comp = parseFloat($(this).children("td:eq(4)").text()); $(this).children("td:eq(4)").addClass(getColorcode(comp, 1+compthres, 1-compthres)); }); + //process average row + $("#results > tfoot > tr").each(function() { + //Color change column + var change = $(this).children("td:eq(2)").text().slice(0, -1); + $(this).children("td:eq(2)").addClass(getColorcode(-change, changethres, -changethres)); + //Color trend column + var trend = $(this).children("td:eq(3)").text().slice(0, -1); + $(this).children("td:eq(3)").addClass(getColorcode(-trend, trendthres, -trendthres)); + }); } function updateTable() { colorTable(); + //process table rows $("#results > tbody > tr").each(function() { //Size plot bars var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); @@ -65,8 +75,15 @@ permalinkToTimeline($(this).children("td:eq(0)").text()); }); }); + //process average row + $("#results > tfoot > tr").each(function() { + //Size plot bar for Average + var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); + var bar = transToLogBars(58, tdwidth, parseFloat($(this).children("td:eq(4)").text())); + $(this).children("td:eq(5)").find("span").css("width", bar["width"]).css("margin-left", bar["margin"]); + }); //Configure table as tablesorter - $.tablesorter.defaults.sortList = [[4,0]];//sort by default by the 5th column + $.tablesorter.defaults.sortList = [[4,1]];//sort by default by the 5th column $.tablesorter.defaults.headers = { 5: { sorter: false } };//disable sorting for bar column $("#results").tablesorter({widgets: ['zebra']}); $("#results tbody td").hover(function() { @@ -104,13 +121,11 @@ {% endblock %} {% block navigation %} - - {% endblock %} {% block body %} Modified: codespeed/pyspeed/templates/overview_table.html ============================================================================== --- codespeed/pyspeed/templates/overview_table.html (original) +++ codespeed/pyspeed/templates/overview_table.html Tue Mar 2 13:14:54 2010 @@ -4,9 +4,12 @@ BenchmarkTime (s)Current changeTrend ({{ trendconfig }})Times cpython
slower
(log2 scale)
faster
+ + Average{{ totals.change|floatformat:2 }}%{{ totals.trend|floatformat:2 }}%{{ totals.relative|floatformat:2 }}- + {% for row in table_list %} - {{ row.benchmark }}{{ row.result|floatformat:3 }}{{ row.change|floatformat:2 }}%{{ row.trend }}{% ifnotequal row.trend "-" %}%{% endifnotequal %}{{ row.relative|floatformat:2 }}- + {{ row.benchmark }}{{ row.result|floatformat:3 }}{{ row.change|floatformat:2 }}%{% ifequal row.trend "-" %}-{% endifequal %}{% ifnotequal row.trend "-" %}{{ row.trend|floatformat:2 }}%{% endifnotequal %}{{ row.relative|floatformat:2 }}- {% endfor %} \ No newline at end of file Modified: codespeed/pyspeed/templates/timeline.html ============================================================================== --- codespeed/pyspeed/templates/timeline.html (original) +++ codespeed/pyspeed/templates/timeline.html Tue Mar 2 13:14:54 2010 @@ -54,7 +54,7 @@ series.push({ "label": $("label[for*='baseline']").html(), "color": seriesColors[id-1], showMarker: false, - lineWidth: 1 + lineWidth: 1.5 }); plotdata.push([[xmin, data["baseline"]], [xmax, data["baseline"]]]); } From tobami at codespeak.net Tue Mar 2 13:31:13 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Tue, 2 Mar 2010 13:31:13 +0100 (CET) Subject: [pypy-svn] r71620 - codespeed/pyspeed/fixtures Message-ID: <20100302123113.2054E51057@codespeak.net> Author: tobami Date: Tue Mar 2 13:31:12 2010 New Revision: 71620 Added: codespeed/pyspeed/fixtures/backup-02-03-2010.json Log: make big fixtures data backup Added: codespeed/pyspeed/fixtures/backup-02-03-2010.json ============================================================================== --- (empty file) +++ codespeed/pyspeed/fixtures/backup-02-03-2010.json Tue Mar 2 13:31:12 2010 @@ -0,0 +1 @@ +[{"pk": 22, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 8}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 2}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_message", "name": "Can add message", "content_type": 4}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 1}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 3}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 2}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_message", "name": "Can change message", "content_type": 4}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 1}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 3}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 2}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_message", "name": "Can delete message", "content_type": 4}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 1}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 3}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_benchmark", "name": "Can add benchmark", "content_type": 11}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_environment", "name": "Can add environment", "content_type": 12}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_interpreter", "name": "Can add interpreter", "content_type": 10}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "add_result", "name": "Can add result", "content_type": 13}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_revision", "name": "Can add revision", "content_type": 9}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_benchmark", "name": "Can change benchmark", "content_type": 11}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "change_environment", "name": "Can change environment", "content_type": 12}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_interpreter", "name": "Can change interpreter", "content_type": 10}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_result", "name": "Can change result", "content_type": 13}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_revision", "name": "Can change revision", "content_type": 9}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_benchmark", "name": "Can delete benchmark", "content_type": 11}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "delete_environment", "name": "Can delete environment", "content_type": 12}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_interpreter", "name": "Can delete interpreter", "content_type": 10}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "delete_result", "name": "Can delete result", "content_type": 13}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_revision", "name": "Can delete revision", "content_type": 9}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 7}}, {"pk": 1, "model": "auth.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": 1, "is_superuser": 1, "is_staff": 1, "last_login": "2010-02-26 04:29:14", "groups": [], "user_permissions": [], "password": "sha1$b0b95$4c4e8730bc9b85fe60473f982088bf0c4d4f86c0", "email": "a at a.es", "date_joined": "2010-01-26 06:05:17"}}, {"pk": 11, "model": "contenttypes.contenttype", "fields": {"model": "benchmark", "name": "benchmark", "app_label": "codespeed"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 12, "model": "contenttypes.contenttype", "fields": {"model": "environment", "name": "environment", "app_label": "codespeed"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 10, "model": "contenttypes.contenttype", "fields": {"model": "interpreter", "name": "interpreter", "app_label": "codespeed"}}, {"pk": 8, "model": "contenttypes.contenttype", "fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "message", "name": "message", "app_label": "auth"}}, {"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 13, "model": "contenttypes.contenttype", "fields": {"model": "result", "name": "result", "app_label": "codespeed"}}, {"pk": 9, "model": "contenttypes.contenttype", "fields": {"model": "revision", "name": "revision", "app_label": "codespeed"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "sites"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": "459091210dde06b3f6d9ec26151831de", "model": "sessions.session", "fields": {"expire_date": "2010-02-09 06:07:11", "session_data": "gAJ9cQEoVRJfYXV0aF91c2VyX2JhY2tlbmRxAlUpZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5k\ncy5Nb2RlbEJhY2tlbmRxA1UNX2F1dGhfdXNlcl9pZHEEigEBdS5lMzBlMjdkMjI0MTk5MzIwODE3\nNTI4ZDMyZjRlODQzZQ==\n"}}, {"pk": "5bbb7e90abcc234173df52612a9275bd", "model": "sessions.session", "fields": {"expire_date": "2010-03-05 07:17:37", "session_data": "gAJ9cQEoVRJfYXV0aF91c2VyX2JhY2tlbmRxAlUpZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5k\ncy5Nb2RlbEJhY2tlbmRxA1UNX2F1dGhfdXNlcl9pZHEEigEBdS5lMzBlMjdkMjI0MTk5MzIwODE3\nNTI4ZDMyZjRlODQzZQ==\n"}}, {"pk": "98500323e6ce3d116bcbe7dc6f463d78", "model": "sessions.session", "fields": {"expire_date": "2010-03-12 04:29:48", "session_data": "gAJ9cQEuYjkzZDg3YWNjNTY3MDJmNjdhMTM3YWQ2ZjY3ZGI0NmI=\n"}}, {"pk": "b5882da2ec0524a0bb0838cc319c7a79", "model": "sessions.session", "fields": {"expire_date": "2010-03-15 18:37:29", "session_data": "gAJ9cQFVCnRlc3Rjb29raWVxAlUGd29ya2VkcQNzLmVjM2Q5MWY1ZDg3MjA2NTc3ZjliNTRiZjRl\nOGRjZmI4\n"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": 15, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:27:06", "object_repr": "rietveld", "object_id": "5", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 14, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:26:20", "object_repr": "spambayes", "object_id": "7", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 13, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:25:57", "object_repr": "spitfire", "object_id": "16", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 12, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:24:03", "object_repr": "slowspitfire", "object_id": "6", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 11, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:23:45", "object_repr": "slowspitfire", "object_id": "6", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 10, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:22:58", "object_repr": "spitfire", "object_id": "16", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 9, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:21:19", "object_repr": "html5lib", "object_id": "3", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 8, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:20:53", "object_repr": "float", "object_id": "8", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 7, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-26 04:20:33", "object_repr": "django", "object_id": "2", "change_message": "Changed description.", "user": 1, "content_type": 11}}, {"pk": 6, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-23 15:14:43", "object_repr": "bigdog", "object_id": "1", "change_message": "Changed cpu, memory and os.", "user": 1, "content_type": 12}}, {"pk": 5, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-19 08:09:39", "object_repr": "bigdog", "object_id": "1", "change_message": "Changed name.", "user": 1, "content_type": 12}}, {"pk": 4, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-02-08 05:07:36", "object_repr": "pypy-c-jit gc=hybrid", "object_id": "2", "change_message": "Changed coptions.", "user": 1, "content_type": 10}}, {"pk": 3, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2010-01-27 05:42:38", "object_repr": "262", "object_id": "3", "change_message": "Changed tag.", "user": 1, "content_type": 9}}, {"pk": 2, "model": "admin.logentry", "fields": {"action_flag": 3, "action_time": "2010-01-27 05:42:21", "object_repr": "2620", "object_id": "1", "change_message": "", "user": 1, "content_type": 9}}, {"pk": 1, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2010-01-26 06:07:22", "object_repr": "Dual Core Linux", "object_id": "1", "change_message": "", "user": 1, "content_type": 12}}, {"pk": 2, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70632}}, {"pk": 3, "model": "codespeed.revision", "fields": {"project": "cpython", "date": null, "message": "", "tag": "2.6.2", "number": 262}}, {"pk": 4, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70634}}, {"pk": 5, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70641}}, {"pk": 6, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70643}}, {"pk": 7, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70671}}, {"pk": 8, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70678}}, {"pk": 9, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70688}}, {"pk": 10, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70694}}, {"pk": 11, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70721}}, {"pk": 12, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70740}}, {"pk": 13, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70764}}, {"pk": 14, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70789}}, {"pk": 15, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70794}}, {"pk": 16, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70813}}, {"pk": 17, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70831}}, {"pk": 18, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70857}}, {"pk": 19, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70901}}, {"pk": 20, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70929}}, {"pk": 21, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70933}}, {"pk": 22, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70961}}, {"pk": 23, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70971}}, {"pk": 24, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 70993}}, {"pk": 25, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71013}}, {"pk": 26, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71019}}, {"pk": 27, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71074}}, {"pk": 28, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71086}}, {"pk": 29, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71091}}, {"pk": 30, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71101}}, {"pk": 31, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71119}}, {"pk": 32, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71129}}, {"pk": 33, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71131}}, {"pk": 34, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71134}}, {"pk": 35, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71140}}, {"pk": 36, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71145}}, {"pk": 37, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71154}}, {"pk": 38, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71212}}, {"pk": 39, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71187}}, {"pk": 40, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71188}}, {"pk": 41, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71202}}, {"pk": 42, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71220}}, {"pk": 43, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71234}}, {"pk": 44, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71250}}, {"pk": 45, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71262}}, {"pk": 46, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71284}}, {"pk": 47, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71314}}, {"pk": 48, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71343}}, {"pk": 49, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71385}}, {"pk": 50, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71388}}, {"pk": 51, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71392}}, {"pk": 52, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71428}}, {"pk": 53, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71432}}, {"pk": 54, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71443}}, {"pk": 55, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71452}}, {"pk": 56, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71473}}, {"pk": 57, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71480}}, {"pk": 58, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71509}}, {"pk": 59, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71525}}, {"pk": 60, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71526}}, {"pk": 61, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 0}}, {"pk": 62, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71544}}, {"pk": 63, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71557}}, {"pk": 64, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71562}}, {"pk": 65, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71576}}, {"pk": 66, "model": "codespeed.revision", "fields": {"project": "pypy", "date": null, "message": "", "tag": "", "number": 71603}}, {"pk": 1, "model": "codespeed.interpreter", "fields": {"coptions": "default", "name": "cpython"}}, {"pk": 3, "model": "codespeed.interpreter", "fields": {"coptions": "gc=hybrid", "name": "pypy-c"}}, {"pk": 2, "model": "codespeed.interpreter", "fields": {"coptions": "gc=hybrid", "name": "pypy-c-jit"}}, {"pk": 1, "model": "codespeed.benchmark", "fields": {"name": "ai", "benchmark_type": "T", "description": ""}}, {"pk": 2, "model": "codespeed.benchmark", "fields": {"name": "django", "benchmark_type": "T", "description": "Uses the Django template system to build a 150x150-cell HTML table"}}, {"pk": 3, "model": "codespeed.benchmark", "fields": {"name": "html5lib", "benchmark_type": "T", "description": "Parses the HTML 5 spec using html5lib"}}, {"pk": 4, "model": "codespeed.benchmark", "fields": {"name": "richards", "benchmark_type": "T", "description": ""}}, {"pk": 5, "model": "codespeed.benchmark", "fields": {"name": "rietveld", "benchmark_type": "T", "description": "Macrobenchmark for Django using the Rietveld code review app"}}, {"pk": 6, "model": "codespeed.benchmark", "fields": {"name": "slowspitfire", "benchmark_type": "T", "description": "Uses the Spitfire template system to build a 1000x1000-cell HTML table"}}, {"pk": 7, "model": "codespeed.benchmark", "fields": {"name": "spambayes", "benchmark_type": "T", "description": "Runs a canned mailbox through a SpamBayes ham/spam classifier"}}, {"pk": 8, "model": "codespeed.benchmark", "fields": {"name": "float", "benchmark_type": "T", "description": "Artificial, floating point-heavy benchmark originally used by Factor"}}, {"pk": 9, "model": "codespeed.benchmark", "fields": {"name": "chaos", "benchmark_type": "T", "description": ""}}, {"pk": 10, "model": "codespeed.benchmark", "fields": {"name": "fannkuch", "benchmark_type": "T", "description": ""}}, {"pk": 11, "model": "codespeed.benchmark", "fields": {"name": "meteor-contest", "benchmark_type": "T", "description": ""}}, {"pk": 12, "model": "codespeed.benchmark", "fields": {"name": "nbody_modified", "benchmark_type": "T", "description": ""}}, {"pk": 13, "model": "codespeed.benchmark", "fields": {"name": "spectral-norm", "benchmark_type": "T", "description": ""}}, {"pk": 14, "model": "codespeed.benchmark", "fields": {"name": "telco", "benchmark_type": "T", "description": ""}}, {"pk": 15, "model": "codespeed.benchmark", "fields": {"name": "gcbench", "benchmark_type": "T", "description": ""}}, {"pk": 16, "model": "codespeed.benchmark", "fields": {"name": "spitfire", "benchmark_type": "T", "description": "Uses the Spitfire template system to build a 1000x1000-cell HTML table, taking advantage of Psyco for acceleration"}}, {"pk": 17, "model": "codespeed.benchmark", "fields": {"name": "spitfire_cstringio", "benchmark_type": "T", "description": ""}}, {"pk": 18, "model": "codespeed.benchmark", "fields": {"name": "twisted_iteration", "benchmark_type": "T", "description": ""}}, {"pk": 19, "model": "codespeed.benchmark", "fields": {"name": "twisted_web", "benchmark_type": "T", "description": ""}}, {"pk": 20, "model": "codespeed.benchmark", "fields": {"name": "twisted_names", "benchmark_type": "T", "description": ""}}, {"pk": 1, "model": "codespeed.environment", "fields": {"memory": "1Gb", "os": "Ubuntu Jaunty", "name": "bigdog", "cpu": "QEMU VM CPU"}}, {"pk": 1, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43707809448200002, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 2, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.65519900322000002, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 3, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.343158960299998, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 4, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029869985580400001, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 5, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.36875300408, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 6, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9608736038200001, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 7, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2217754364, "environment": 1, "date": "2010-01-27 09:41:22", "interpreter": 2, "result_type": "T", "revision": 2}}, {"pk": 8, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42444438934299999, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 9, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.82142634391799996, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 10, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 11.6034450531, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 11, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.29558792114299998, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 12, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 0.48473563194300001, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 13, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 0.66251654624900003, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 14, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 0.26918497085600002, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 15, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42492904663100001, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 16, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.62576680183400002, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 17, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.203540086699999, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 18, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029346752166800001, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 19, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3492350578300001, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 20, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9761237621300001, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 21, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.3172614097599999, "environment": 1, "date": "2010-01-27 09:41:23", "interpreter": 2, "result_type": "T", "revision": 4}}, {"pk": 22, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.442705011368, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 23, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.69898595809899999, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 24, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 19.623087883, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 25, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031779193878200003, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 26, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.35385112762, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 27, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.0196122646300001, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 28, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2326191902200001, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 5}}, {"pk": 29, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.427397823334, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 30, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.64163026809699997, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 31, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.129413127900001, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 32, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031384038925200003, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 33, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.38800883293, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 34, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.97738900185, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 35, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2374196052499999, "environment": 1, "date": "2010-01-27 09:41:24", "interpreter": 2, "result_type": "T", "revision": 6}}, {"pk": 36, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44572839736999997, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 37, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.619217777252, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 38, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.536835908899999, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 39, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031195306778, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 40, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.37284536361, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 41, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9654173851000001, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 42, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.21845993996, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 7}}, {"pk": 43, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43448724746700002, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 44, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.65551400184599995, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 45, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.218690061569, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 46, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.542385101299999, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 47, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030475807189899999, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 48, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.34365615845, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 49, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.00317382812, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 50, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2182968139699999, "environment": 1, "date": "2010-01-27 09:41:25", "interpreter": 2, "result_type": "T", "revision": 8}}, {"pk": 51, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.422487783432, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 52, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.121007490158, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 53, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.64096617698699998, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 54, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37990322113000002, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 55, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.135547828674, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 56, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.0433809757, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 57, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.37866396903999999, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 58, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.076025152206400007, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 59, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029587221145600001, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 60, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.33778300285, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 61, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.95510158539, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 62, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.21777257919, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 63, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.062807464599600002, "environment": 1, "date": "2010-01-27 09:41:26", "interpreter": 2, "result_type": "T", "revision": 9}}, {"pk": 64, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42574295997599998, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 65, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.116217041016, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 66, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.67578072547900003, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 67, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.391155767441, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 68, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.12938299179099999, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 69, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.0490338802, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 70, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38244643211399998, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 71, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.075785207748500005, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 72, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030660200118999999, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 73, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.33663039207, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 74, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9485769748699999, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 75, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.22385950089, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 76, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.063131237029999995, "environment": 1, "date": "2010-01-27 09:41:27", "interpreter": 2, "result_type": "T", "revision": 10}}, {"pk": 77, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43206744194000002, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 78, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.120690727234, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 79, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.62421946525600003, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 80, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.373276233673, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 81, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.15013499259999999, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 82, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.6344439983, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 83, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38476510047899998, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 84, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.077058410644600006, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 85, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030047035217300001, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 86, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3758056163800001, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 87, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.0055235862699998, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 88, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2375351429000001, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 89, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.063822555542000003, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 90, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.65200000000000002, "environment": 1, "date": "2010-01-27 09:41:28", "interpreter": 2, "result_type": "T", "revision": 11}}, {"pk": 91, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43032097816499998, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 92, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11874918937700001, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 93, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.65952877998299997, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 94, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38479938507099998, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 95, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.148169994354, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 96, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.341817855799999, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 97, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38457193374600002, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 98, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079361963272, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 99, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030018854141200001, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 100, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3934579849299999, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 101, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9659803867300001, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 102, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.24824433327, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 103, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.0622970581055, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 104, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.624, "environment": 1, "date": "2010-01-27 09:41:29", "interpreter": 2, "result_type": "T", "revision": 12}}, {"pk": 105, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42947344780000002, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 106, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.118019390106, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 107, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.64448981285100004, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 108, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39367756843500001, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 109, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.131764364243, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 110, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 7.6069629192399999, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 111, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.664299011200001, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 112, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38062396049500002, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 113, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079070186614999996, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 114, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029060602188099999, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 115, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.36374936104, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 116, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9975749492599999, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 117, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2262028217300001, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 118, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067093992233299996, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 119, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.63600000000000001, "environment": 1, "date": "2010-01-27 09:41:30", "interpreter": 2, "result_type": "T", "revision": 13}}, {"pk": 120, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43611154556300002, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 121, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.122742033005, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 122, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.67777743339499996, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 123, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38444399833699999, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 124, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.146523761749, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 125, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 7.8365619182600001, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 126, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 19.585288047799999, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 127, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39473080635000002, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 128, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.074167156219499999, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 129, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0297776699066, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 130, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.45638175011, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 131, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9965989589699999, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 132, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.26717119217, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 133, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065821361541800003, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 134, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.63400000000000001, "environment": 1, "date": "2010-01-27 09:41:31", "interpreter": 2, "result_type": "T", "revision": 14}}, {"pk": 135, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.426050901413, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 136, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.122226619721, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 137, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.67538876533500003, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 138, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38024778366099998, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 139, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.142001438141, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 140, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 7.6646499633799996, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 141, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 19.0767159462, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 142, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38860616683999999, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 143, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.074223804473800004, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 144, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030911397933999999, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 145, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.4178003788, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 146, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.95840940476, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 147, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2289570808400001, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 148, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068292617797899996, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 149, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.64400000000000002, "environment": 1, "date": "2010-01-27 09:41:32", "interpreter": 2, "result_type": "T", "revision": 15}}, {"pk": 150, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43184123039299999, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 151, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.128963375091, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 152, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.67031297683699997, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 153, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37783699035599999, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 154, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14520840644800001, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 155, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 7.7148549556699999, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 156, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 19.313369989400002, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 157, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.40089354515100001, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 158, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.076049709320000006, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 159, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030450057983399999, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 160, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.41337842941, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 161, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.0009929657000001, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 162, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2717852592500001, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 163, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067063713073700001, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 164, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.68799999999999994, "environment": 1, "date": "2010-01-27 09:41:33", "interpreter": 2, "result_type": "T", "revision": 16}}, {"pk": 165, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.428143215179, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 166, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.117868947983, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 167, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.585657787323, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 168, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38937940597499998, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 169, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.130286979675, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 170, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4381451606800004, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 171, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 19.300865888600001, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 172, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39005379676800001, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 173, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.073681354522599996, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 174, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.027494049072299999, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 175, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.39566936493, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 176, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9981239795700001, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 177, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.21310677528, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 178, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.0675278663635, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 179, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.53000000000000003, "environment": 1, "date": "2010-01-27 09:41:34", "interpreter": 2, "result_type": "T", "revision": 17}}, {"pk": 180, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42251968383799998, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 181, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11669778823800001, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 182, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.629346036911, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 183, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39522018432599998, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 184, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14308924675000001, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 185, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0056009292599999, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 186, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.969789028200001, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 187, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38797254562400002, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 188, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.072004508972299999, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 189, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.027719545364400001, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 190, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.4016525745399999, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 191, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.0152218341800001, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 192, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2458042144799999, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 193, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066313076019300005, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 194, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.52000000000000002, "environment": 1, "date": "2010-01-27 09:41:35", "interpreter": 2, "result_type": "T", "revision": 18}}, {"pk": 195, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44146103859000002, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 196, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.116399478912, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 197, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.56150536537200002, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 198, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37951617240899999, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 199, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14459261894200001, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 200, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2366421222700001, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 201, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 18.872216939899999, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 202, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.386883449554, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 203, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.077071142196599995, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 204, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029833173751799998, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 205, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.35280065537, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 206, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9402369976, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 207, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1963545799299999, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 208, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066495370864899997, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 209, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.46600000000000003, "environment": 1, "date": "2010-01-27 09:59:21", "interpreter": 2, "result_type": "T", "revision": 19}}, {"pk": 210, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.42351732254000002, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 211, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.7979119777699999, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 212, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.51181406974800003, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 213, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 27.097495079000002, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 214, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.31325550079300002, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 215, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.53843350410400004, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 216, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.50088262557999996, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 217, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.05, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 218, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43200035095200001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 219, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.117177915573, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 220, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.53456697464000003, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 221, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37750501632700001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 222, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.143707418442, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 223, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0006799697900002, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 224, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.459820032100001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 225, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39029078483599999, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 226, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.072830963134800003, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 227, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029026174545300001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 228, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.4049810409600001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 229, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9356455802899999, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 230, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2247850418099999, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 231, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068435764312700001, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 232, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.47799999999999998, "environment": 1, "date": "2010-02-08 12:57:07", "interpreter": 2, "result_type": "T", "revision": 20}}, {"pk": 233, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42829480171200002, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 234, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.124062108994, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 235, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.56471238136299995, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 236, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38404459953300002, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 237, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.142818832398, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 238, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2628729343399998, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 239, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.444487094900001, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 240, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39220576286300002, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 241, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.073698616027800007, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 242, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.02878241539, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 243, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3572861671400001, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 244, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.99017038345, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 245, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2404726028399999, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 246, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067131233215400002, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 247, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.47999999999999998, "environment": 1, "date": "2010-02-08 12:57:08", "interpreter": 2, "result_type": "T", "revision": 21}}, {"pk": 248, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43037562370299998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 249, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.121508789063, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 250, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50206098556500001, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 251, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37895998954799998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 252, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14183044433600001, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 253, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1084389686599998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 254, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.209439992899998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 255, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38838734626799998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 256, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.074748563766500006, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 257, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028778171539299999, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 258, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.36066980362, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 259, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9895885467500001, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 260, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2577526569399999, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 261, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067212057113599996, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 262, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.47799999999999998, "environment": 1, "date": "2010-02-08 12:57:09", "interpreter": 2, "result_type": "T", "revision": 22}}, {"pk": 263, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45690660476700001, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 264, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.120519590378, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 265, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.54817218780499999, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 266, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39389805793799998, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 267, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.15938162803600001, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 268, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1659770011899999, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 269, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.709064960500001, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 270, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39093775749199999, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 271, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079464387893800004, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 272, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029051446914700001, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 273, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.33928961754, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 274, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8708491325400001, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 275, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2492036342599999, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 276, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068829250335700004, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 277, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.46999999999999997, "environment": 1, "date": "2010-02-08 12:57:10", "interpreter": 2, "result_type": "T", "revision": 23}}, {"pk": 278, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44754805564900002, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 279, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.12157001495399999, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 280, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.53904900550799995, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 281, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39877815246600001, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 282, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.141833972931, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 283, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1433038711499997, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 284, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.2865948677, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 285, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38513965606700001, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 286, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078276109695500001, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 287, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028567647934, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 288, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3498888492600001, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 289, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5695494651799999, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 290, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.2771122932500001, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 291, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065087032318099994, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 292, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.47999999999999998, "environment": 1, "date": "2010-02-08 12:57:11", "interpreter": 2, "result_type": "T", "revision": 24}}, {"pk": 293, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43687658309900002, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 294, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11778059005700001, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 295, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.55812158584600002, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 296, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39432578086800002, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 297, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14308495521600001, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 298, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1556611061100002, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 299, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.827883958800001, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 300, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.37860097885100003, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 301, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.0791513442993, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 302, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028306150436400002, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 303, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3929077625299999, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 304, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.57587604523, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 305, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.22806482315, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 306, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066839694976799993, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 307, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.496, "environment": 1, "date": "2010-02-08 12:57:13", "interpreter": 2, "result_type": "T", "revision": 25}}, {"pk": 308, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45311346054099999, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 309, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.120071363449, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 310, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.52496376037600001, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 311, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38780541419999998, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 312, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.128447532654, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 313, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9577949047100001, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 314, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 16.4755749702, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 315, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38462038040199997, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 316, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078198528289700003, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 317, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028803586959799999, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 318, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.35955696106, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 319, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5860638141600001, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 320, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.23515124321, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 321, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.070180845260600005, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 322, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.46400000000000002, "environment": 1, "date": "2010-02-08 12:57:14", "interpreter": 2, "result_type": "T", "revision": 26}}, {"pk": 323, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44099764823900001, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 324, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.116354751587, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 325, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49744930267300003, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 326, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38121018409700003, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 327, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.143323135376, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 328, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9482378959700002, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 329, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.7915890217, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 330, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38683800697300003, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 331, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079219770431399994, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 332, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0284921646118, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 333, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.34892821312, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 334, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5913082599599999, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 335, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.22848973274, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 336, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066678333282500002, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 337, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.432, "environment": 1, "date": "2010-02-08 12:57:15", "interpreter": 2, "result_type": "T", "revision": 27}}, {"pk": 338, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43412504196200002, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 339, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11484541893, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 340, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.51569437980699995, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 341, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38811478614799999, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 342, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14066257476800001, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 343, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1109030246699998, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 344, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.547342062, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 345, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.51018061637900003, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 346, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079201698303299997, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 347, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.027072429657000002, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 348, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3053493976599999, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 349, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5995460510199999, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 350, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.09114394188, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 351, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067341756820699997, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 352, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.41999999999999998, "environment": 1, "date": "2010-02-08 12:57:16", "interpreter": 2, "result_type": "T", "revision": 28}}, {"pk": 353, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43453879356399999, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 354, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11760058403, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 355, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50038580894499995, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 356, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38978376388500002, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 357, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.126835155487, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 358, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0113921165499997, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 359, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.472515106199999, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 360, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.37842659950300001, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 361, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.081173038482699994, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 362, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028962564468399999, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 363, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3032561779, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 364, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5998044490800001, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 365, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0052612304699999, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 366, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067598628997800003, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 367, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42799999999999999, "environment": 1, "date": "2010-02-08 12:57:17", "interpreter": 2, "result_type": "T", "revision": 29}}, {"pk": 368, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43935694694499999, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 369, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11619195938100001, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 370, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.53101701736499995, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 371, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38734254836999998, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 372, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.142231178284, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 373, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0254831314099997, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 374, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.6835122108, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 375, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38142361640900002, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 376, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078077650070199997, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 377, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0292743682861, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 378, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3089139461499999, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 379, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.60704088211, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 380, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0411904335, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 381, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067225265502900006, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 382, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.434, "environment": 1, "date": "2010-02-08 12:57:18", "interpreter": 2, "result_type": "T", "revision": 30}}, {"pk": 383, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44037966728200001, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 384, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11571192741399999, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 385, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.51071386337299995, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 386, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38245801925700001, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 387, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.125499439239, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 388, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.8924760818499999, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 389, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.6689431667, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 390, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.382358026505, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 391, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078869438171400005, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 392, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0268948078156, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 393, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.31747603416, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 394, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5961161613499999, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 395, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.02343401909, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 396, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065925025939900003, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 397, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42599999999999999, "environment": 1, "date": "2010-02-08 12:57:19", "interpreter": 2, "result_type": "T", "revision": 31}}, {"pk": 398, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44511313438400002, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 399, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.123738050461, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 400, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.52820878028899998, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 401, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38264322280899998, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 402, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14330682754499999, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 403, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9724481105800002, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 404, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.7132329941, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 405, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38648300170900002, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 406, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.080526351928700002, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 407, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028388643264799999, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 408, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3175216197999999, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 409, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6084318161, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 410, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0272073745700001, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 411, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066053199768099993, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 412, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.8099999999999996, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 413, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.5720000000000001, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 414, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42599999999999999, "environment": 1, "date": "2010-02-08 12:57:20", "interpreter": 2, "result_type": "T", "revision": 32}}, {"pk": 415, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.453927755356, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 416, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.121992349625, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 417, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.52232122421299998, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 418, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38407201766999999, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 419, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.141575145721, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 420, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.06002688408, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 421, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.3287079334, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 422, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.387917757034, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 423, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.083066082000799998, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 424, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.026917457580600001, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 425, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.31879124642, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 426, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.62367901802, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 427, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0268442153899999, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 428, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067343568801899997, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 429, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.6859999999999999, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 430, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4279999999999999, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 431, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.438, "environment": 1, "date": "2010-02-08 12:57:22", "interpreter": 2, "result_type": "T", "revision": 33}}, {"pk": 432, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.483631706238, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 433, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11660304069499999, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 434, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.51569676399200004, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 435, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.382478189468, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 436, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.12743959426900001, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 437, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2178769111600003, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 438, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.719299078000001, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 439, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38842058181799999, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 440, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079445600509699996, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 441, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.027382421493600002, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 442, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3188374519399999, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 443, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5849890232099999, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 444, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.01821317673, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 445, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065883016586299997, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 446, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1040000000000001, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 447, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3739999999999997, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 448, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.436, "environment": 1, "date": "2010-02-08 12:57:23", "interpreter": 2, "result_type": "T", "revision": 34}}, {"pk": 449, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45719275474499999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 450, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.120211029053, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 451, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50765895843499997, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 452, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.390260744095, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 453, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14059381485, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 454, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9633219242099997, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 455, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.672068119, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 456, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38170418739299999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 457, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.081372261047299999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 458, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028692531585699999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 459, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3357413768799999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 460, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6702152728999999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 461, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0448349475900001, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 462, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068740367889399995, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 463, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.4039999999999999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 464, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.5380000000000003, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 465, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42999999999999999, "environment": 1, "date": "2010-02-08 12:57:24", "interpreter": 2, "result_type": "T", "revision": 35}}, {"pk": 466, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45246744155899998, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 467, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.115577602386, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 468, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.53764219284100001, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 469, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39720401763899998, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 470, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14264602661100001, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 471, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9869220256800002, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 472, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.157873868899999, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 473, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38921575546300002, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 474, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.080121755599999997, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 475, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.03005900383, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 476, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.35679936409, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 477, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5685717582700001, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 478, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0374664306600001, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 479, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.070476913452099998, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 480, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.0640000000000001, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 481, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3639999999999999, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 482, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42599999999999999, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 483, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036658235272600002, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 484, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62893081761000003, "environment": 1, "date": "2010-02-08 12:57:25", "interpreter": 2, "result_type": "T", "revision": 36}}, {"pk": 485, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.451867008209, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 486, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.122903156281, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 487, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.52295198440599999, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 488, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39611358642599998, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 489, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14402337074300001, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 490, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0354669094100002, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 491, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.4241089821, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 492, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38023424148500001, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 493, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.080273628234900002, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 494, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029130172729500001, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 495, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3123150825500001, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 496, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5844192027999999, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 497, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0873519897499999, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 498, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065541601180999998, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 499, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1159999999999997, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 500, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3780000000000001, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 501, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.432, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 502, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036170852297399997, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 503, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.61728395061700003, "environment": 1, "date": "2010-02-22 13:50:11", "interpreter": 2, "result_type": "T", "revision": 37}}, {"pk": 504, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.016, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 505, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.6460000000000008, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 506, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.148112381751, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 507, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.119760479042, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 508, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43322672843900001, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 509, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11744904518099999, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 510, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.48571481704699998, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 511, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38401727676399999, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 512, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.15490598678600001, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 513, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3500790595999996, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 514, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.6703209877, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 515, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38782238960299997, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 516, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078919744491499993, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 517, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029299402236899998, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 518, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3126312732700001, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 519, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6204295635199999, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 520, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.01780185699, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 521, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066225481033300004, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 522, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.2779999999999996, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 523, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.306, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 524, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42199999999999999, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 525, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035354803126799998, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 526, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.625, "environment": 1, "date": "2010-02-23 07:11:03", "interpreter": 2, "result_type": "T", "revision": 38}}, {"pk": 527, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.430691766739, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 528, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11717157363900001, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 529, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.514612388611, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 530, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.393562173844, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 531, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14185461998000001, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 532, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2862169742600003, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 533, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.7301180363, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 534, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38952765464799999, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 535, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078011417388999998, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 536, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030347156524699999, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 537, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.29316658974, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 538, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.55049118996, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 539, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0247521877300001, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 540, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066597604751599995, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 541, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.0620000000000003, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 542, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3179999999999996, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 543, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.432, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 544, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036612159703699999, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 545, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.61349693251500004, "environment": 1, "date": "2010-02-22 13:50:12", "interpreter": 2, "result_type": "T", "revision": 39}}, {"pk": 546, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42884359359699997, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 547, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.114629793167, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 548, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49477019309999998, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 549, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39401621818499999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 550, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.144149160385, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 551, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2031950950599999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 552, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.641324043299999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 553, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38706464767499998, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 554, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.077932405471799998, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 555, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028376531601, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 556, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.30154781342, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 557, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.60555825233, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 558, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.05130105019, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 559, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066271257400499994, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 560, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.4960000000000004, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 561, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3760000000000003, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 562, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.442, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 563, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036362723989799998, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 564, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62111801242200004, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 40}}, {"pk": 565, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.42880434989900001, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 566, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.12032480239899999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 567, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50316696166999997, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 568, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.388308906555, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 569, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14445853233299999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 570, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.33303499222, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 571, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.8706271648, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 572, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39889183044400001, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 573, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079198551177900006, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 574, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0296399593353, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 575, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3223052024899999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 576, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.64126338959, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 577, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.04748206138, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 578, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066780710220299994, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 579, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.4100000000000001, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 580, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.2519999999999998, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 581, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42799999999999999, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 582, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036406794964199997, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 583, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.625, "environment": 1, "date": "2010-02-22 13:50:13", "interpreter": 2, "result_type": "T", "revision": 41}}, {"pk": 584, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.43862233161899999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 585, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.123193025589, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 586, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.53653941154499996, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 587, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.381501626968, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 588, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14009056091300001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 589, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1545431613900003, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 590, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.7329018116, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 591, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39437122344999997, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 592, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.078885030746599999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 593, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0277119636536, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 594, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3141985893300001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 595, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.58513402939, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 596, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0044934272799999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 597, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.071096849441500007, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 598, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.048, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 599, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.7880000000000003, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 600, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.42999999999999999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 601, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036226633821199998, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 602, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62111801242200004, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 42}}, {"pk": 603, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44809217453, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 604, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.113735437393, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 605, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50106139182999998, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 606, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39928603172299998, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 607, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14171442985499999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 608, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2781009674100003, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 609, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.5502259731, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 610, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39536585807800001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 611, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079635190963800007, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 612, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0281164646149, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 613, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3367244243600001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 614, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5766518592800001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 615, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.04758167267, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 616, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.065478754043599999, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 617, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1120000000000001, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 618, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.2839999999999998, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 619, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.434, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 620, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035202727225700003, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 621, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62111801242200004, "environment": 1, "date": "2010-02-22 13:50:15", "interpreter": 2, "result_type": "T", "revision": 43}}, {"pk": 622, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44513745307899999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 623, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.121272754669, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 624, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49722375869699997, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 625, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39374003410399999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 626, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14083724021899999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 627, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3038730621300001, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 628, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.5741548538, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 629, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38799338340799999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 630, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.081650590896599998, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 631, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0283284187317, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 632, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.2966595649699999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 633, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5907944679199999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 634, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.02476892471, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 635, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066187715530399996, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 636, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1280000000000001, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 637, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4059999999999997, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 638, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.44, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 639, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036464144806399999, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 640, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.61349693251500004, "environment": 1, "date": "2010-02-22 13:50:16", "interpreter": 2, "result_type": "T", "revision": 44}}, {"pk": 641, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.444679403305, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 642, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11603541374199999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 643, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.501110553741, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 644, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38651690483099999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 645, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.12641596794099999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 646, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 4.9901590347300004, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 647, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.0504281521, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 648, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38429880142200001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 649, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.079768466949399999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 650, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028708219528200001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 651, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3060919761700001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 652, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6433506011900001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 653, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0471677780199999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 654, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066263961792000003, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 655, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1260000000000003, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 656, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.8920000000000003, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 657, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.434, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 658, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036082716018199998, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 659, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.61728395061700003, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 45}}, {"pk": 660, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.47966413497900001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 661, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.12769103050200001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 662, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49365983009300002, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 663, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39229197502099999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 664, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.12834277153000001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 665, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0687980651900002, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 666, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.0278940201, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 667, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38894824981699999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 668, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.089199447631800002, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 669, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031850814819300001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 670, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.31683301926, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 671, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5949654579100001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 672, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0184495925899999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 673, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067186117172199994, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 674, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1040000000000001, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 675, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3719999999999999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 676, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.436, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 677, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.037156847226699999, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 678, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62111801242200004, "environment": 1, "date": "2010-02-22 13:50:17", "interpreter": 2, "result_type": "T", "revision": 46}}, {"pk": 679, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45030741691600001, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 680, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.12841868400600001, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 681, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49538087844799999, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 682, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38673725128199998, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 683, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14405679702800001, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 684, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3096809387199997, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 685, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.751036882399999, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 686, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38835844993599999, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 687, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.084215450286900001, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 688, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0287984848023, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 689, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.3020512103999999, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 690, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.60323505402, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 691, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0276945591, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 692, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066935873031599993, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 693, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1020000000000003, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 694, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3499999999999996, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 695, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.436, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 696, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036920259623299999, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 697, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.62111801242200004, "environment": 1, "date": "2010-02-22 13:50:18", "interpreter": 2, "result_type": "T", "revision": 47}}, {"pk": 698, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.82477416992200003, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 699, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60206642150900003, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 700, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.36654295921, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 701, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0027895450600002, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 702, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62338137626699996, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 703, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.400223970399999, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 704, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.7271881104, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 705, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.56917352676400002, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 706, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.47060441970799999, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 707, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.39701581001300001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 708, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.1005847930899999, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 709, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.3264100074799998, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 710, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.12871608734, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 711, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.73006982803300002, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 712, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 13.608000000000001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 713, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 10.602, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 714, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 2.0499999999999998, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 33}}, {"pk": 715, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.84513964652999995, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 716, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60191202163699997, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 717, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.33260784149, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 718, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.91208238602, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 719, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62002520561200003, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 720, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.039499998099998, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 721, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.0058350563, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 722, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54553537368799998, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 723, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46591038703900001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 724, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.393785429001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 725, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.06237754822, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 726, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8074742794000001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 727, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1310554981200001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 728, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.74119162559499996, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 729, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.69, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 730, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.8940000000000001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 731, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8640000000000001, "environment": 1, "date": "2010-02-19 16:08:20", "interpreter": 3, "result_type": "T", "revision": 34}}, {"pk": 732, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.82429704666100001, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 733, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.64444694519099999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 734, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3891027927399999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 735, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.88681240082, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 736, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.63113179206799996, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 737, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.6499958038, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 738, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.3453910351, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 739, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.56427459716799999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 740, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45401077270500001, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 741, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.399842166901, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 742, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0861895561199999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 743, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1729546070099999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 744, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1470741272, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 745, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.81053409576400004, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 746, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.906000000000001, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 747, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 10.036, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 748, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9319999999999999, "environment": 1, "date": "2010-02-19 16:08:21", "interpreter": 3, "result_type": "T", "revision": 35}}, {"pk": 749, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81729073524499996, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 750, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60419778823799997, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 751, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3336909771000001, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 752, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.8685907363900001, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 753, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62722463607800005, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 754, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.211711883500001, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 755, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.213441133500002, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 756, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.545457029343, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 757, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.44319858551000002, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 758, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.38666386604300002, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 759, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0961834430699999, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 760, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1912564754499999, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 761, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1196137428299999, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 762, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.73046774864200004, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 763, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.832000000000001, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 764, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.9100000000000001, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 765, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.966, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 766, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.33651225241100002, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 767, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22421524663699999, "environment": 1, "date": "2010-02-19 16:08:22", "interpreter": 3, "result_type": "T", "revision": 36}}, {"pk": 768, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.79749684333799997, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 769, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61308960914599997, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 770, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.30101675987, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 771, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.90628948212, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 772, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.67123160362300005, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 773, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.249785184899999, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 774, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.109343051900002, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 775, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55449948310800001, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 776, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46671156883199999, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 777, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40526518821700003, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 778, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.08151521683, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 779, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8464411735499999, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 780, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.13508119583, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 781, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.798368501663, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 782, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.276, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 783, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.5600000000000005, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 784, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8240000000000001, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 785, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31230090817099998, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 786, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22172949002199999, "environment": 1, "date": "2010-02-22 13:50:50", "interpreter": 3, "result_type": "T", "revision": 37}}, {"pk": 787, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.83035979271000004, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 788, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60074591636700003, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 789, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3346575736999999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 790, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9715472698200001, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 791, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64911155700699996, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 792, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.670989990199999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 793, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.622494935999999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 794, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.53635263443000003, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 795, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46351580619799998, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 796, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.39642324447600003, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 797, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0690033435799999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 798, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1434367656700002, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 799, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.13720517158, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 800, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.82075018882799999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 801, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.308, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 802, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.1999999999999993, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 803, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8300000000000001, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 804, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32250574060199999, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 805, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22026431718100001, "environment": 1, "date": "2010-02-22 13:50:51", "interpreter": 3, "result_type": "T", "revision": 39}}, {"pk": 806, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81249780654899995, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 807, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60438241958600003, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 808, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3172108173399999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 809, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9098683834100001, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 810, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.615597724914, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 811, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.1788218021, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 812, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.9537820816, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 813, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.56479210853600004, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 814, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46403212547299999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 815, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40978136062600001, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 816, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0841445922899999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 817, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.2318727493299999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 818, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.14017772674, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 819, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.79409842491100002, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 820, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.529999999999999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 821, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.7360000000000007, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 822, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8979999999999999, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 823, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.327959175642, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 824, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22675736961500001, "environment": 1, "date": "2010-02-22 13:50:52", "interpreter": 3, "result_type": "T", "revision": 40}}, {"pk": 825, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.79013576507600003, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 826, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.59992961883499996, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 827, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.37495040894, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 828, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0804708004000001, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 829, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.63301577568, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 830, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.648062944399999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 831, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.675555944399999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 832, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.56692299842799998, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 833, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45670142173799999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 834, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41493639945999999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 835, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.08938102722, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 836, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1204952716799998, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 837, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1762467861200001, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 838, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.85524315834099995, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 839, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.34, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 840, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0899999999999999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 841, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8720000000000001, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 842, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.33690792643299999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 843, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.228832951945, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 41}}, {"pk": 844, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.85355405807499996, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 845, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.62819538116499996, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 846, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3379057407399999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 847, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9366400241899999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 848, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.63744120597800003, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 849, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.020072936999998, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 850, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.6028900146, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 851, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54798460006700001, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 852, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.47037715911900002, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 853, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40876960754399999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 854, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0835155010199999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 855, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1811104297599999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 856, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1400179863, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 857, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.78229937553399997, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 858, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.51, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 859, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0820000000000007, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 860, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8759999999999999, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 861, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.30985365611799998, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 862, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22321428571400001, "environment": 1, "date": "2010-02-22 13:50:53", "interpreter": 3, "result_type": "T", "revision": 38}}, {"pk": 863, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.80612177848800004, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 864, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.63574557304400003, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 865, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3749926567099999, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 866, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9882120132400001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 867, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64184756278999999, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 868, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.0659239292, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 869, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.008901834500001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 870, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55423078537000003, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 871, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45567989349400001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 872, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.43450298309300001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 873, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.11993894577, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 874, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1544956207300001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 875, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1387714386000001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 876, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.75036334991499998, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 877, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.282, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 878, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0079999999999991, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 879, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9139999999999999, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 880, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32344769365600001, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 881, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22935779816499999, "environment": 1, "date": "2010-02-22 13:50:54", "interpreter": 3, "result_type": "T", "revision": 42}}, {"pk": 882, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.80018930435199997, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 883, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.59213438033999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 884, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3235432147999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 885, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9277043819399999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 886, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62833967208899999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 887, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.127498865100002, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 888, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.327387809800001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 889, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.56621112823499997, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 890, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45159125328100003, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 891, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.38968000411999998, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 892, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0736969471, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 893, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1472087860100002, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 894, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.13990058899, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 895, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.77609677314799996, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 896, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.045999999999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 897, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.3460000000000001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 898, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8240000000000001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 899, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32112006679299998, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 900, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22271714921999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 43}}, {"pk": 901, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.80318298339799998, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 902, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61232824325599999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 903, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3392906189, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 904, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9800031661999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 905, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64127964973499996, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 906, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.156852006899999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 907, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.053118228900001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 908, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55627279281599995, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 909, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45560183525100001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 910, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41682891845699999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 911, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0842313289600001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 912, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.20537576675, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 913, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1362669944799999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 914, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.77727856636100001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 915, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.422000000000001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 916, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0340000000000007, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 917, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8919999999999999, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 918, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32001843306200001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 919, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22321428571400001, "environment": 1, "date": "2010-02-22 13:50:55", "interpreter": 3, "result_type": "T", "revision": 44}}, {"pk": 920, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.818012475967, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 921, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60698575973500002, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 922, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.2975725650800001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 923, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9775249958100001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 924, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62256784439099999, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 925, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.1509029865, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 926, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.7618701458, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 927, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.58412351608299995, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 928, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.48972077369700001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 929, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40206174850499998, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 930, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0852341651899999, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 931, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.17764463425, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 932, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1558308124500001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 933, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.73517060279900004, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 934, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.656000000000001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 935, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.2460000000000004, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 936, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8140000000000001, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 937, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.311458560439, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 938, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.225733634312, "environment": 1, "date": "2010-02-22 13:50:56", "interpreter": 3, "result_type": "T", "revision": 45}}, {"pk": 939, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.825184011459, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 940, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60307979583799998, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 941, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3379285812399999, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 942, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.97367358208, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 943, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.63664975166299997, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 944, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.364063978200001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 945, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.421370983100001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 946, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55586194992100002, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 947, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.47209377288799997, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 948, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41157622337400002, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 949, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.07824172973, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 950, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1591178417200001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 951, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1331048965399999, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 952, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.782281541824, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 953, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.128, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 954, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.9540000000000006, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 955, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8400000000000001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 956, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32229577728100001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 957, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22624434389100001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 46}}, {"pk": 958, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.83132643699599995, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 959, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61693515777600005, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 960, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.38650422096, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 961, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.94930934906, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 962, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.62898721694899995, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 963, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.428918123199999, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 964, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.086130857499999, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 965, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54965958595300002, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 966, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.472414779663, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 967, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40663475990300002, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 968, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.1000701904300001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 969, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1739943981200001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 970, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1460503578200001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 971, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.79650421142600003, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 972, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.506, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 973, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.8940000000000001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 974, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9239999999999999, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 975, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32730760041000001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 976, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23255813953500001, "environment": 1, "date": "2010-02-22 13:50:57", "interpreter": 3, "result_type": "T", "revision": 47}}, {"pk": 977, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44249439239499999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 978, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.115298175812, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 979, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.47745585441600003, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 980, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38079981803899998, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 981, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14702963828999999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 982, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0517730712900004, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 983, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.591430902500001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 984, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.386064386368, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 985, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085122537612900007, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 986, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031057214736899999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 987, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0331740379300001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 988, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.59146933556, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 989, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0149888515500001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 990, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066960000991799995, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 991, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1219999999999999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 992, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4880000000000004, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 993, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.44600000000000001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 994, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.037968733507299998, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 995, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.19801980197999999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 48}}, {"pk": 996, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44992356300399999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 997, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11578998565699999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 998, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.52114281654399996, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 999, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38190956115699998, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1000, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14550876617399999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1001, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4469690322900002, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1002, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.040622949599999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1003, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39632396698, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1004, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.087449455261099998, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1005, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0308654308319, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1006, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.02835979462, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1007, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6254161357900001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1008, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0877672195400001, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1009, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068438577651999996, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1010, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.282, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1011, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.7880000000000003, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1012, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.45800000000000002, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1013, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.069796139435900004, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1014, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0113739763421, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1015, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23584905660399999, "environment": 1, "date": "2010-02-22 13:50:19", "interpreter": 2, "result_type": "T", "revision": 49}}, {"pk": 1016, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44951915740999998, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1017, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.119570827484, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1018, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50683159828199997, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1019, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38480520248400002, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1020, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.13045554161100001, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1021, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.0542590618099998, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1022, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.618311882, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1023, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38234896659899997, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1024, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085056781768799994, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1025, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028561258316, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1026, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 0.99944243431099999, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1027, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5851112842599999, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1028, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.04048018456, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1029, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068225431442300005, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1030, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1639999999999997, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1031, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3200000000000003, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1032, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.438, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1033, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.071269182991499994, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1034, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.010442773600700001, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1035, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23980815347699999, "environment": 1, "date": "2010-02-22 13:50:20", "interpreter": 2, "result_type": "T", "revision": 50}}, {"pk": 1036, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45416383743299998, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1037, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11950340271, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1038, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.50190320015000001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1039, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38935637474099999, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1040, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.141454029083, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1041, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1508920192699996, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1042, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.764722108799999, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1043, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39560799598700003, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1044, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085687160491900005, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1045, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.032861232757600001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1046, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0266308307700001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1047, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6459937572500001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1048, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.03217101097, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1049, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067571258544899995, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1050, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.218, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1051, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3300000000000001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1052, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.44, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1053, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.073424619715500003, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1054, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0103723680116, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1055, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.21978021978000001, "environment": 1, "date": "2010-02-25 17:41:31", "interpreter": 2, "result_type": "T", "revision": 51}}, {"pk": 1056, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.82982683181799999, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1057, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60214085578900001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1058, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3062074184400001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1059, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9530392646800001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1060, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.68191056251500004, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1061, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.747576951999999, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1062, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.599431991599999, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1063, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55478401184100001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1064, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46533699035600001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1065, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40102734565699999, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1066, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0711554050400001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1067, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1195827484100001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1068, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.12413043976, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1069, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.80542078018200003, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1070, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.284000000000001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1071, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0139999999999993, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1072, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8600000000000001, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1073, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.320771905513, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1074, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22421524663699999, "environment": 1, "date": "2010-02-22 13:50:58", "interpreter": 3, "result_type": "T", "revision": 48}}, {"pk": 1075, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.82888002395600002, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1076, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61254525184599995, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1077, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3402440071099999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1078, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0057998180399998, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1079, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64979376792900001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1080, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.7988710403, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1081, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.237363100100001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1082, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.576547431946, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1083, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46138100624099998, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1084, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.425237989426, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1085, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.11317052841, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1086, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.2928051948600001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1087, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1661899089800001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1088, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.74127879142800002, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1089, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.648, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1090, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.1419999999999995, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1091, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.972, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1092, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.34889765784999999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1093, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017879492222400001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1094, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.24154589371999999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 49}}, {"pk": 1095, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.80748338699300004, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1096, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.64595766067500004, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1097, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.34966516495, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1098, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9725692272199999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1099, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.67069840431200001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1100, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.412612915, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1101, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.542129039799999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1102, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55608296394400003, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1103, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46792197227499999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1104, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.43663582801799999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1105, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.12121682167, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1106, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1302556514700002, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1107, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1370074749000001, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1108, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.77292299270599996, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1109, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.385999999999999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1110, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.766, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1111, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8839999999999999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1112, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.34493463488699999, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1113, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0181653042688, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1114, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.25773195876299998, "environment": 1, "date": "2010-02-22 13:50:59", "interpreter": 3, "result_type": "T", "revision": 50}}, {"pk": 1115, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.839103937149, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1116, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.62290124893200005, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1117, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.352064991, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1118, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.96297559738, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1119, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.66007223129299997, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1120, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.4323091507, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1121, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.007483005499999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1122, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.57246360778799998, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1123, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45583200454700001, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1124, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40182261467000002, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1125, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0838566303299999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1126, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.2438461780600001, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1127, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1411762237500001, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1128, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.77591519355799998, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1129, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.869999999999999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1130, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.9039999999999999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1131, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9219999999999999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1132, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.34908156639900001, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1133, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.018047283883799999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1134, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23640661938499999, "environment": 1, "date": "2010-02-25 17:42:36", "interpreter": 3, "result_type": "T", "revision": 51}}, {"pk": 1135, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0089007565643100008, "environment": 1, "date": "2010-02-22 22:50:46", "interpreter": 1, "result_type": "T", "revision": 3}}, {"pk": 1136, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.448057985306, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1137, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.11555995941199999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1138, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.49367198944099999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1139, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38178725242599998, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1140, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14414062499999999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1141, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.26692891121, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1142, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.8284919262, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1143, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39418716430700002, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1144, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.084006786346499995, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1145, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0311054229736, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1146, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0089781761200001, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1147, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5698737621300001, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1148, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0389833450299999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1149, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067387390136700004, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1150, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1619999999999999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1151, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3520000000000003, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1152, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.436, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1153, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.038059802606600003, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1154, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0103519668737, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1155, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22172949002199999, "environment": 1, "date": "2010-02-25 17:41:37", "interpreter": 2, "result_type": "T", "revision": 52}}, {"pk": 1156, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44408721923799999, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1157, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.112195158005, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1158, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.51022124290500004, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1159, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.388197803497, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1160, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14437212944, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1161, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2189810275999999, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1162, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.086513996100001, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1163, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38531522750800001, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1164, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085148906707700006, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1165, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030429601669300001, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1166, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.03384494782, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1167, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.59535541534, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1168, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0123787879899999, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1169, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067564201355000006, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1170, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1399999999999997, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1171, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3860000000000001, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1172, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.44400000000000001, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1173, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.037619866299, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1174, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0102711585867, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1175, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22123893805299999, "environment": 1, "date": "2010-02-25 17:41:43", "interpreter": 2, "result_type": "T", "revision": 53}}, {"pk": 1176, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81052999496400002, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1177, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60681195259099996, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1178, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3620525836999999, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1179, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0445516109500002, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1180, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.66781439781200003, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1181, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.898710966100001, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1182, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.466968059500001, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1183, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54495458602900004, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1184, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45498123168900001, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1185, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41278085708599999, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1186, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.11716094017, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1187, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1672815322900001, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1188, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1426439285300001, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1189, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.81872644424399998, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1190, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.182, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1191, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.4760000000000009, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1192, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.982, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1193, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32717160150500002, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1194, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.018073377914299998, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1195, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23584905660399999, "environment": 1, "date": "2010-02-25 17:42:41", "interpreter": 3, "result_type": "T", "revision": 52}}, {"pk": 1196, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81454219818100004, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1197, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.58032360076900003, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1198, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3387816429099999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1199, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.97203726769, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1200, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.63259410858200005, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1201, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 20.859583854699999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1202, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.379150867500002, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1203, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.57165603637700002, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1204, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45756387710599999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1205, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.39372558593700002, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1206, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0734197616600001, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1207, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.1528988361299999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1208, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1308839798000001, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1209, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.79903836250299998, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1210, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.738, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1211, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.4019999999999992, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1212, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8859999999999999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1213, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32575199848899999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1214, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017908309455599999, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1215, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.2331002331, "environment": 1, "date": "2010-02-25 17:42:47", "interpreter": 3, "result_type": "T", "revision": 53}}, {"pk": 1216, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45804414749099998, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1217, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.115968990326, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1218, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.48907217979399997, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1219, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38519783019999998, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1220, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14626255035399999, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1221, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.1265881061599998, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1222, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.7702999115, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1223, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39003753662099999, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1224, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.084774303436300005, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1225, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029919195175199999, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1226, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0257995605500001, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1227, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.62077980042, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1228, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0428582668299999, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1229, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.070467472076500004, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1230, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.242, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1231, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.298, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1232, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.442, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1233, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.037317470920399998, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1234, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0099304865938400003, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1235, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22727272727299999, "environment": 1, "date": "2010-02-25 17:41:49", "interpreter": 2, "result_type": "T", "revision": 54}}, {"pk": 1236, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.444884967804, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1237, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.108579969406, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1238, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.453775405884, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1239, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.384858369827, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1240, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.128339385986, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1241, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3236289024400003, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1242, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.518028020899999, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1243, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38674168586699997, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1244, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085645389556900001, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1245, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0302715778351, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1246, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 0.96801753044000005, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1247, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.6657386302899999, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1248, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0189362049099999, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1249, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.066940832138099995, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1250, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.0620000000000003, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1251, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.2999999999999998, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1252, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.39400000000000002, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1253, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.034491500432, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1254, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0096964995636599997, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1255, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.21881838074400001, "environment": 1, "date": "2010-02-25 17:41:55", "interpreter": 2, "result_type": "T", "revision": 55}}, {"pk": 1256, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45656323432899998, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1257, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.100545215607, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1258, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.44828081131000003, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1259, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.384632444382, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1260, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.147346925735, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1261, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.21665978432, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1262, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.8010621071, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1263, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38664641380300002, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1264, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.084958982467600003, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1265, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029856157302900001, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1266, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 0.99990673065299995, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1267, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5721438884700001, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1268, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.02581982613, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1269, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.067750024795500005, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1270, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.016, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1271, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3460000000000001, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1272, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.376, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1273, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035244700430599997, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1274, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095428953144399992, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1275, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.21321961620499999, "environment": 1, "date": "2010-02-25 17:42:01", "interpreter": 2, "result_type": "T", "revision": 56}}, {"pk": 1276, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.46178841590899999, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1277, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.1129591465, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1278, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.43405041694699997, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1279, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38426795005800002, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1280, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.15274157524099999, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1281, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.7065730094899996, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1282, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.9334080219, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1283, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39407739639299999, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1284, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.088228225707899996, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1285, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.031113147735599998, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1286, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.01411137581, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1287, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.61271309852, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1288, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.07136049271, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1289, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.074827194213800005, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1290, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1319999999999997, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1291, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4139999999999997, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1292, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.38200000000000001, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1293, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036029881742699998, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1294, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095593155530099994, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1295, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22421524663699999, "environment": 1, "date": "2010-02-26 18:59:54", "interpreter": 2, "result_type": "T", "revision": 57}}, {"pk": 1296, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.85082454681399999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1297, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61203422546399999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1298, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3484340667700001, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1299, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.98840494156, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1300, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.66602497100799996, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1301, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.658634900999999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1302, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.885036945300001, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1303, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55738453865000004, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1304, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46480779647800002, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1305, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41746883392299999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1306, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.08952593804, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1307, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 2.2202427864100001, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1308, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.13921570778, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1309, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.79952316284199998, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1310, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.948, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1311, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0920000000000005, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1312, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9199999999999999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1313, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.313706790811, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1314, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017847581652699999, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1315, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.238663484487, "environment": 1, "date": "2010-02-25 17:42:53", "interpreter": 3, "result_type": "T", "revision": 54}}, {"pk": 1316, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.79085426330599995, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1317, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60729656219499994, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1318, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3056642055500001, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1319, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0160846233399998, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1320, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.65244479179399995, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1321, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.919422149700001, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1322, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.3051650524, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1323, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54550724029499997, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1324, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.465325450897, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1325, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.39617018699599998, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1326, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0816519737200001, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1327, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8300115585300001, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1328, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1155103206600001, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1329, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.76063995361299996, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1330, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.464, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1331, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.8759999999999994, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1332, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9299999999999999, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1333, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31936739706, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1334, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0176616036736, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1335, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23584905660399999, "environment": 1, "date": "2010-02-25 17:42:59", "interpreter": 3, "result_type": "T", "revision": 55}}, {"pk": 1336, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81474299430800001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1337, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60512480735800001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1338, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.2889076232900001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1339, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9643778324100001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1340, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64361505508399997, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1341, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.331362962699998, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1342, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.8378589153, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1343, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55839338302599995, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1344, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45960297584499998, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1345, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40125541686999999, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1346, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0857021331800001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1347, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8316388130200001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1348, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1152890682200001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1349, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.77295160293599996, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1350, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.374000000000001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1351, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.7119999999999997, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1352, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8160000000000001, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1353, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31291559101900002, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1354, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017847581652699999, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1355, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.234741784038, "environment": 1, "date": "2010-02-25 17:43:05", "interpreter": 3, "result_type": "T", "revision": 56}}, {"pk": 1356, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.822621583938, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1357, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.630578756332, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1358, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.29953403473, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1359, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9671210289000001, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1360, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.66527023315400002, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1361, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.566417932499998, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1362, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.973475933100001, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1363, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55666618347200003, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1364, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.482868957519, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1365, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.394734144211, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1366, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.11282200813, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1367, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.91158242226, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1368, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1191850185400001, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1369, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.80140380859399996, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1370, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 13.284000000000001, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1371, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.5299999999999994, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1372, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8180000000000001, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1373, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32664900584399997, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1374, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017503938386099999, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1375, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23584905660399999, "environment": 1, "date": "2010-02-25 17:43:11", "interpreter": 3, "result_type": "T", "revision": 57}}, {"pk": 1376, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44489483833299998, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1377, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.105377578735, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1378, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.457850837708, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1379, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.37966885566699998, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1380, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14510221481300001, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1381, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4667971134200002, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1382, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.5440018177, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1383, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39170231819200002, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1384, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085892868041999998, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1385, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.029967641830399998, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1386, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0068406105000001, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1387, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.54476356506, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1388, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0442651271800001, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1389, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.069172906875600002, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1390, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.0720000000000001, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1391, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3339999999999996, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1392, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.38, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1393, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035657234139699998, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1394, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095066070919300003, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1395, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22371364653199999, "environment": 1, "date": "2010-02-27 21:43:46", "interpreter": 2, "result_type": "T", "revision": 58}}, {"pk": 1396, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81667156219500003, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1397, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.615085601807, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1398, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.32389659881, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1399, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.04861159325, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1400, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.65821557045000001, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1401, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.099758148199999, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1402, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.639731884, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1403, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54571781158400001, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1404, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.47730937004099999, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1405, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40550541877700003, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1406, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0857443332700001, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1407, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.81036801338, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1408, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1507472515099999, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1409, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.809006977081, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1410, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.1, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1411, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.6479999999999997, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1412, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9239999999999999, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1413, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.34295199358, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1414, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.018142235123400002, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1415, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23809523809499999, "environment": 1, "date": "2010-02-27 21:44:21", "interpreter": 3, "result_type": "T", "revision": 58}}, {"pk": 1416, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.46689500808700002, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1417, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.101242828369, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1418, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.461251974106, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1419, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.40458841323799999, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1420, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14812512397800001, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1421, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4392459392500001, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1422, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.2095711231, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1423, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38774418830899998, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1424, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.084470415115299999, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1425, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0286624908447, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1426, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 0.96723861694400004, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1427, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.57787842751, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1428, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0276158332800001, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1429, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.069204616546599998, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1430, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1319999999999997, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1431, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3159999999999998, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1432, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.376, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1433, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035623382475799999, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1434, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095165588123299998, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1435, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.215982721382, "environment": 1, "date": "2010-02-27 21:43:53", "interpreter": 2, "result_type": "T", "revision": 59}}, {"pk": 1436, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44878969192500001, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1437, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.102875375748, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1438, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.44437599182100002, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1439, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38299818038900002, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1440, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.147850465775, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1441, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3565158844000003, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1442, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.7846372128, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1443, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38794851303099998, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1444, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.088661241531399995, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1445, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.033090448379500002, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1446, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.03507781029, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1447, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.55236797333, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1448, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0271584034000001, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1449, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068535995483400003, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1450, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.2400000000000002, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1451, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4299999999999997, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1452, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.38200000000000001, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1453, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.034904087059199999, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1454, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095156532495999993, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1455, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22172949002199999, "environment": 1, "date": "2010-02-28 19:33:09", "interpreter": 2, "result_type": "T", "revision": 60}}, {"pk": 1456, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.83027701377899998, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1457, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.63213887214700004, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1458, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.42247524261, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1459, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9096373557999999, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1460, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.67448458671599998, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1461, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.167097091700001, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1462, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.9996509552, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1463, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.555860853195, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1464, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.466407012939, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1465, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41221237182600001, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1466, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.08523554802, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1467, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.85844759941, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1468, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.11829023361, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1469, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.80534501075800002, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1470, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.31, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1471, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.8480000000000008, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1472, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8879999999999999, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1473, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31432900188000001, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1474, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017956545160699999, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1475, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.240384615385, "environment": 1, "date": "2010-02-27 21:44:27", "interpreter": 3, "result_type": "T", "revision": 59}}, {"pk": 1476, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.847062635422, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1477, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60602283477800001, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1478, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.2716722011599999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1479, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9713500022899999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1480, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.67579350471499999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1481, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.250501871099999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1482, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.9543099403, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1483, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55667443275399997, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1484, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45424156188999998, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1485, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.41209263801599999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1486, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.05464816093, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1487, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8427532196, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1488, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1250155925800001, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1489, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.79359149932899997, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1490, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.778, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1491, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 10.24, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1492, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8200000000000001, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1493, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32223761802000001, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1494, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0176273576591, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1495, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.24154589371999999, "environment": 1, "date": "2010-02-28 19:33:38", "interpreter": 3, "result_type": "T", "revision": 60}}, {"pk": 1496, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45392632484399997, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1497, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.10515236854600001, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1498, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.46378026008599998, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1499, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39573121070900003, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1500, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.14984130859399999, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1501, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4562458991999998, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1502, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.3465771675, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1503, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.393889474869, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1504, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085029458999600002, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1505, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.030173635482799999, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1506, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0155347824100001, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1507, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5645229816399999, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1508, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0234948158299999, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1509, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.069688177108699997, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1510, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.024, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1511, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3399999999999999, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1512, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.38200000000000001, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1513, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.0347887073073, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1514, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0095840521372399998, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1515, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22779043280200001, "environment": 1, "date": "2010-02-28 19:33:14", "interpreter": 2, "result_type": "T", "revision": 62}}, {"pk": 1516, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45768628120400001, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1517, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.102807283401, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1518, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.44194078445399998, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1519, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.39308223724399999, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1520, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.148639535904, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1521, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.47355914116, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1522, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.3875479698, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1523, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38404874801599997, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1524, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.085509252548199993, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1525, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0290965557098, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1526, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.01390161514, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1527, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5859676361099999, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1528, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0421810150099999, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1529, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.068690395355199996, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1530, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.2140000000000004, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1531, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.4720000000000004, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1532, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.378, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1533, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.034278177004299998, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1534, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0097228974234300006, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1535, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.22624434389100001, "environment": 1, "date": "2010-02-28 19:33:21", "interpreter": 2, "result_type": "T", "revision": 63}}, {"pk": 1536, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.84530577659600004, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1537, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.65466022491499998, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1538, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.32963061333, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1539, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 2.0214459896100001, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1540, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.65645537376399998, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1541, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.7919268608, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1542, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.792870044699999, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1543, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.57997598648100002, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1544, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.46688303947499998, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1545, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.42110581398000002, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1546, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.09828057289, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1547, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8856233596800001, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1548, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.15739431381, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1549, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.83371262550299996, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1550, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 13.012, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1551, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.9580000000000002, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1552, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8640000000000001, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1553, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32444778986200001, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1554, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017730496453899999, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1555, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.24330900243299999, "environment": 1, "date": "2010-02-28 19:33:44", "interpreter": 3, "result_type": "T", "revision": 62}}, {"pk": 1556, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.84411401748600001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1557, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.61131138801600005, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1558, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.2597750186900001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1559, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.9098272323600001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1560, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.64554233550999995, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1561, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 22.6058950424, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1562, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 30.589322090100001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1563, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.565101003647, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1564, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.47021636962899999, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1565, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40374174118, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1566, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0665364742300001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1567, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.9011094093300001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1568, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.14229836464, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1569, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.78607759475700001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1570, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 13.246, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1571, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.6679999999999993, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1572, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8759999999999999, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1573, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31259964113599997, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1574, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017780938833600001, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1575, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23584905660399999, "environment": 1, "date": "2010-02-28 19:33:50", "interpreter": 3, "result_type": "T", "revision": 63}}, {"pk": 1576, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44622616767899997, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1577, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.107070589066, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1578, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.43866982460100001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1579, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38838577270500002, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1580, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.15012764930700001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1581, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.4506390094799997, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1582, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 13.067947864500001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1583, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.40876240730300001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1584, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.088262462616000001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1585, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.028443384170500002, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1586, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.06712737083, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1587, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.59952788353, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1588, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0184711933099999, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1589, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.072306680679300003, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1590, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.1079999999999997, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1591, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.2679999999999998, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1592, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.38, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1593, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.0359476113891, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1594, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0089686098654700001, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1595, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.21929824561399999, "environment": 1, "date": "2010-02-28 14:27:59", "interpreter": 2, "result_type": "T", "revision": 64}}, {"pk": 1596, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.83433814048800004, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1597, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.64714412689199996, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1598, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.3383019924199999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1599, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.95747179985, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1600, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.671983814239, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1601, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 23.567461013799999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1602, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.516593933100001, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1603, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54677157402099996, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1604, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.48577184677099999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1605, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.40487165451099999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1606, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.1173414230400001, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1607, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8498204231299999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1608, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1754987716700001, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1609, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.80178961753800004, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1610, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 13.119999999999999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1611, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0440000000000005, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1612, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.8959999999999999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1613, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.32424790698, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1614, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017550017550000001, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1615, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.24449877750599999, "environment": 1, "date": "2010-02-28 14:33:40", "interpreter": 3, "result_type": "T", "revision": 64}}, {"pk": 1616, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.44191761016800002, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1617, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.10400633812, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1618, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.43336944580100001, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1619, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38262453079199998, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1620, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.147160387039, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1621, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.2604360580399998, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1622, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.004042863800001, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1623, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.39151244163499999, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1624, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.0865023612976, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1625, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.0307010650635, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1626, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0037835598, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1627, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.59009137154, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1628, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0323631286599999, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1629, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.0668954372406, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1630, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.2619999999999996, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1631, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.2919999999999998, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1632, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.378, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1633, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.036066891098900003, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1634, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0088245675961900003, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1635, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.206611570248, "environment": 1, "date": "2010-02-28 21:24:00", "interpreter": 2, "result_type": "T", "revision": 65}}, {"pk": 1636, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.81694869995099995, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1637, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.60080008506799998, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1638, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.29332318306, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1639, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.94990301132, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1640, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.627879810333, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1641, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 21.8504049778, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1642, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 31.166146040000001, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1643, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.54563751220699996, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1644, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45113015174799997, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1645, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.39523072242700003, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1646, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0735355853999999, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1647, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.85528740883, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1648, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.14838995934, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1649, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.74506740570100005, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1650, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.51, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1651, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 8.8819999999999997, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1652, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9419999999999999, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1653, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.31149348667100002, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1654, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017442874585699999, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1655, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.23752969121100001, "environment": 1, "date": "2010-02-28 21:29:44", "interpreter": 3, "result_type": "T", "revision": 65}}, {"pk": 1656, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.45410990714999999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1657, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.10466055870099999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1658, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 0.45182080268800001, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1659, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 0.38567900657699999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1660, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.146999073028, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1661, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 5.3140039443999996, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1662, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 12.571560144399999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1663, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.38504338264400001, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1664, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.0867322444917, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1665, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.032523155212399998, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1666, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.02836461067, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1667, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.5925312042199999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1668, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.0333966732099999, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1669, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.069301605224599994, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1670, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 7.234, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1671, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 4.3860000000000001, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1672, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 0.372, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1673, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.035737259666900001, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1674, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.0089206066012500005, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1675, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.215517241379, "environment": 1, "date": "2010-03-01 21:24:03", "interpreter": 2, "result_type": "T", "revision": 66}}, {"pk": 1676, "model": "codespeed.result", "fields": {"benchmark": 1, "value": 0.82377424240099995, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1677, "model": "codespeed.result", "fields": {"benchmark": 9, "value": 0.632643413544, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1678, "model": "codespeed.result", "fields": {"benchmark": 2, "value": 1.34495921135, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1679, "model": "codespeed.result", "fields": {"benchmark": 10, "value": 1.95318017006, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1680, "model": "codespeed.result", "fields": {"benchmark": 8, "value": 0.68747582435599996, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1681, "model": "codespeed.result", "fields": {"benchmark": 15, "value": 24.735080957400001, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1682, "model": "codespeed.result", "fields": {"benchmark": 3, "value": 32.807960987100003, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1683, "model": "codespeed.result", "fields": {"benchmark": 11, "value": 0.55493221283000005, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1684, "model": "codespeed.result", "fields": {"benchmark": 12, "value": 0.45760521888799999, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1685, "model": "codespeed.result", "fields": {"benchmark": 4, "value": 0.42563171386699999, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1686, "model": "codespeed.result", "fields": {"benchmark": 5, "value": 1.0995021819999999, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1687, "model": "codespeed.result", "fields": {"benchmark": 6, "value": 1.8535705089600001, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1688, "model": "codespeed.result", "fields": {"benchmark": 7, "value": 1.1260583877599999, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1689, "model": "codespeed.result", "fields": {"benchmark": 13, "value": 0.78196883201599998, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1690, "model": "codespeed.result", "fields": {"benchmark": 16, "value": 12.554, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1691, "model": "codespeed.result", "fields": {"benchmark": 17, "value": 9.0600000000000005, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1692, "model": "codespeed.result", "fields": {"benchmark": 14, "value": 1.9379999999999999, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1693, "model": "codespeed.result", "fields": {"benchmark": 18, "value": 0.34095132237999998, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1694, "model": "codespeed.result", "fields": {"benchmark": 20, "value": 0.017470300489200001, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}, {"pk": 1695, "model": "codespeed.result", "fields": {"benchmark": 19, "value": 0.2331002331, "environment": 1, "date": "2010-03-01 21:29:48", "interpreter": 3, "result_type": "T", "revision": 66}}] From arigo at codespeak.net Tue Mar 2 13:58:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 13:58:06 +0100 (CET) Subject: [pypy-svn] r71627 - pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc Message-ID: <20100302125806.13A7951057@codespeak.net> Author: arigo Date: Tue Mar 2 13:58:05 2010 New Revision: 71627 Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Log: Replace tabs with \t. I know it doesn't look as good, but it's needed to make test_tab happy. Another solution would be to turn these bits of text into their own files. Modified: pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/trackgcroot.py Tue Mar 2 13:58:05 2010 @@ -1246,36 +1246,36 @@ long pypy_asm_stackwalk(void *callback) { __asm { - mov edx, DWORD PTR [esp+4] ; my argument, which is the callback - mov eax, esp ; my frame top address - push eax ; ASM_FRAMEDATA[6] - push ebp ; ASM_FRAMEDATA[5] - push edi ; ASM_FRAMEDATA[4] - push esi ; ASM_FRAMEDATA[3] - push ebx ; ASM_FRAMEDATA[2] + mov\tedx, DWORD PTR [esp+4]\t; my argument, which is the callback + mov\teax, esp\t\t; my frame top address + push\teax\t\t\t; ASM_FRAMEDATA[6] + push\tebp\t\t\t; ASM_FRAMEDATA[5] + push\tedi\t\t\t; ASM_FRAMEDATA[4] + push\tesi\t\t\t; ASM_FRAMEDATA[3] + push\tebx\t\t\t; ASM_FRAMEDATA[2] ; Add this ASM_FRAMEDATA to the front of the circular linked ; list. Let's call it 'self'. - mov eax, DWORD PTR [__gcrootanchor+4] ; next = gcrootanchor->next - push eax ; self->next = next - push OFFSET __gcrootanchor ; self->prev = gcrootanchor - mov DWORD PTR [__gcrootanchor+4], esp ; gcrootanchor->next = self - mov DWORD PTR [eax+0], esp ; next->prev = self + mov\teax, DWORD PTR [__gcrootanchor+4]\t\t; next = gcrootanchor->next + push\teax\t\t\t\t\t\t\t\t\t; self->next = next + push\tOFFSET __gcrootanchor ; self->prev = gcrootanchor + mov\tDWORD PTR [__gcrootanchor+4], esp\t\t; gcrootanchor->next = self + mov\tDWORD PTR [eax+0], esp\t\t\t\t\t; next->prev = self - call edx ; invoke the callback + call\tedx\t\t\t\t\t\t; invoke the callback ; Detach this ASM_FRAMEDATA from the circular linked list - pop esi ; prev = self->prev - pop edi ; next = self->next - mov DWORD PTR [esi+4], edi ; prev->next = next - mov DWORD PTR [edi+0], esi ; next->prev = prev - - pop ebx ; restore from ASM_FRAMEDATA[2] - pop esi ; restore from ASM_FRAMEDATA[3] - pop edi ; restore from ASM_FRAMEDATA[4] - pop ebp ; restore from ASM_FRAMEDATA[5] - pop ecx ; ignored ASM_FRAMEDATA[6] + pop\tesi\t\t\t\t\t\t\t; prev = self->prev + pop\tedi\t\t\t\t\t\t\t; next = self->next + mov\tDWORD PTR [esi+4], edi\t\t; prev->next = next + mov\tDWORD PTR [edi+0], esi\t\t; next->prev = prev + + pop\tebx\t\t\t\t; restore from ASM_FRAMEDATA[2] + pop\tesi\t\t\t\t; restore from ASM_FRAMEDATA[3] + pop\tedi\t\t\t\t; restore from ASM_FRAMEDATA[4] + pop\tebp\t\t\t\t; restore from ASM_FRAMEDATA[5] + pop\tecx\t\t\t\t; ignored ASM_FRAMEDATA[6] ; the return value is the one of the 'call' above, ; because %eax (and possibly %edx) are unmodified ret @@ -1293,37 +1293,37 @@ print >> output, """\ /* See description in asmgcroot.py */ - movl 4(%esp), %edx /* my argument, which is the callback */ - movl %esp, %eax /* my frame top address */ - pushl %eax /* ASM_FRAMEDATA[6] */ - pushl %ebp /* ASM_FRAMEDATA[5] */ - pushl %edi /* ASM_FRAMEDATA[4] */ - pushl %esi /* ASM_FRAMEDATA[3] */ - pushl %ebx /* ASM_FRAMEDATA[2] */ + movl\t4(%esp), %edx\t/* my argument, which is the callback */ + movl\t%esp, %eax\t/* my frame top address */ + pushl\t%eax\t\t/* ASM_FRAMEDATA[6] */ + pushl\t%ebp\t\t/* ASM_FRAMEDATA[5] */ + pushl\t%edi\t\t/* ASM_FRAMEDATA[4] */ + pushl\t%esi\t\t/* ASM_FRAMEDATA[3] */ + pushl\t%ebx\t\t/* ASM_FRAMEDATA[2] */ /* Add this ASM_FRAMEDATA to the front of the circular linked */ /* list. Let's call it 'self'. */ - movl __gcrootanchor + 4, %eax /* next = gcrootanchor->next */ - pushl %eax /* self->next = next */ - pushl $__gcrootanchor /* self->prev = gcrootanchor */ - movl %esp, __gcrootanchor + 4 /* gcrootanchor->next = self */ - movl %esp, 0(%eax) /* next->prev = self */ + movl\t__gcrootanchor + 4, %eax\t/* next = gcrootanchor->next */ + pushl\t%eax\t\t\t\t/* self->next = next */ + pushl\t$__gcrootanchor\t\t\t/* self->prev = gcrootanchor */ + movl\t%esp, __gcrootanchor + 4\t/* gcrootanchor->next = self */ + movl\t%esp, 0(%eax)\t\t\t/* next->prev = self */ /* note: the Mac OS X 16 bytes aligment must be respected. */ - call *%edx /* invoke the callback */ + call\t*%edx\t\t/* invoke the callback */ /* Detach this ASM_FRAMEDATA from the circular linked list */ - popl %esi /* prev = self->prev */ - popl %edi /* next = self->next */ - movl %edi, 4(%esi) /* prev->next = next */ - movl %esi, 0(%edi) /* next->prev = prev */ - - popl %ebx /* restore from ASM_FRAMEDATA[2] */ - popl %esi /* restore from ASM_FRAMEDATA[3] */ - popl %edi /* restore from ASM_FRAMEDATA[4] */ - popl %ebp /* restore from ASM_FRAMEDATA[5] */ - popl %ecx /* ignored ASM_FRAMEDATA[6] */ + popl\t%esi\t\t/* prev = self->prev */ + popl\t%edi\t\t/* next = self->next */ + movl\t%edi, 4(%esi)\t/* prev->next = next */ + movl\t%esi, 0(%edi)\t/* next->prev = prev */ + + popl\t%ebx\t\t/* restore from ASM_FRAMEDATA[2] */ + popl\t%esi\t\t/* restore from ASM_FRAMEDATA[3] */ + popl\t%edi\t\t/* restore from ASM_FRAMEDATA[4] */ + popl\t%ebp\t\t/* restore from ASM_FRAMEDATA[5] */ + popl\t%ecx\t\t/* ignored ASM_FRAMEDATA[6] */ /* the return value is the one of the 'call' above, */ /* because %eax (and possibly %edx) are unmodified */ @@ -1346,8 +1346,8 @@ .align 4 .globl __gcrootanchor __gcrootanchor: - .long __gcrootanchor /* prev */ - .long __gcrootanchor /* next */ + .long\t__gcrootanchor /* prev */ + .long\t__gcrootanchor /* next */ """.replace("__gcrootanchor", _globalname("__gcrootanchor")) shapes = {} From arigo at codespeak.net Tue Mar 2 14:05:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:05:03 +0100 (CET) Subject: [pypy-svn] r71629 - in pypy/trunk/pypy: rpython/memory/gctransform translator/c translator/c/gcc translator/c/gcc/test translator/c/gcc/test/darwin translator/c/gcc/test/elf translator/c/gcc/test/msvc translator/c/src Message-ID: <20100302130503.75A3C282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:05:01 2010 New Revision: 71629 Added: pypy/trunk/pypy/translator/c/gcc/test/darwin/track9.s - copied unchanged from r71628, pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/darwin/track9.s pypy/trunk/pypy/translator/c/gcc/test/elf/track9.s - copied unchanged from r71628, pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/elf/track9.s pypy/trunk/pypy/translator/c/gcc/test/msvc/track9.s - copied unchanged from r71628, pypy/branch/asmgcc-cantcollect/pypy/translator/c/gcc/test/msvc/track9.s Modified: pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py pypy/trunk/pypy/rpython/memory/gctransform/framework.py pypy/trunk/pypy/translator/c/gcc/instruction.py pypy/trunk/pypy/translator/c/gcc/test/elf/track5.s pypy/trunk/pypy/translator/c/gcc/test/msvc/track0.s pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/trunk/pypy/translator/c/gcc/trackgcroot.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/src/mem.h Log: Merge of branch/asmgcc-cantcollect: Don't analyze in trackgcroot calls to functions that cannot collect. Some of these are very small and the C compiler perform some optimizations that we don't want to follow. Modified: pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py Tue Mar 2 14:05:01 2010 @@ -40,6 +40,9 @@ def build_root_walker(self): return AsmStackRootWalker(self) + def mark_call_cannotcollect(self, hop, name): + hop.genop("direct_call", [c_asm_nocollect, name]) + def gct_direct_call(self, hop): fnptr = hop.spaceop.args[0].value try: @@ -487,6 +490,12 @@ _nowrapper=True) c_asm_gcroot = Constant(pypy_asm_gcroot, lltype.typeOf(pypy_asm_gcroot)) +pypy_asm_nocollect = rffi.llexternal('pypy_asm_gc_nocollect', + [rffi.CCHARP], lltype.Void, + sandboxsafe=True, + _nowrapper=True) +c_asm_nocollect = Constant(pypy_asm_nocollect, lltype.typeOf(pypy_asm_nocollect)) + QSORT_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([llmemory.Address, llmemory.Address], rffi.INT)) qsort = rffi.llexternal('qsort', Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py Tue Mar 2 14:05:01 2010 @@ -40,7 +40,12 @@ return True return graphanalyze.GraphAnalyzer.analyze_direct_call(self, graph, seen) - + def analyze_external_call(self, op, seen=None): + funcobj = op.args[0].value._obj + if funcobj._name == 'pypy_asm_stackwalk': + return True + return graphanalyze.GraphAnalyzer.analyze_external_call(self, op, + seen) def analyze_simple_operation(self, op): if op.opname in ('malloc', 'malloc_varsize'): flags = op.args[1].value @@ -577,6 +582,11 @@ self.pop_roots(hop, livevars) else: self.default(hop) + if hop.spaceop.opname == "direct_call": + self.mark_call_cannotcollect(hop, hop.spaceop.args[0]) + + def mark_call_cannotcollect(self, hop, name): + pass gct_indirect_call = gct_direct_call Modified: pypy/trunk/pypy/translator/c/gcc/instruction.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/instruction.py (original) +++ pypy/trunk/pypy/translator/c/gcc/instruction.py Tue Mar 2 14:05:01 2010 @@ -164,8 +164,8 @@ return dict(zip(self.registers, self.registers)) class InsnCall(Insn): - _args_ = ['lineno', 'gcroots'] - def __init__(self, lineno): + _args_ = ['lineno', 'name', 'gcroots'] + def __init__(self, name, lineno): # 'gcroots' is a dict built by side-effect during the call to # FunctionGcRootTracker.trackgcroots(). Its meaning is as # follows: the keys are the locations that contain gc roots @@ -189,12 +189,13 @@ # %ebx from there in the prologue and epilogue). self.gcroots = {} self.lineno = lineno + self.name = name def source_of(self, localvar, tag): tag1 = self.gcroots.setdefault(localvar, tag) assert tag1 == tag, ( - "conflicting entries for InsnCall.gcroots[%s]:\n%r and %r" % ( - localvar, tag1, tag)) + "conflicting entries for\n%s.gcroots[%s]:\n%r and %r" % ( + self, localvar, tag1, tag)) return localvar def all_sources_of(self, localvar): Modified: pypy/trunk/pypy/translator/c/gcc/test/elf/track5.s ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/elf/track5.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/elf/track5.s Tue Mar 2 14:05:01 2010 @@ -42,9 +42,9 @@ call pypy_g_SemiSpaceGC_get_size ;; expected {28(%esp) | 20(%esp), 24(%esp), %edi, %ebp | } addl %eax, %ebx + jmp .L1221 .L1227: call RPyAbort - ;; expected {28(%esp) | 20(%esp), 24(%esp), %edi, %ebp | } cmpl 12(%esi), %ebx jb .L1229 addl $20, %esp Modified: pypy/trunk/pypy/translator/c/gcc/test/msvc/track0.s ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/msvc/track0.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/msvc/track0.s Tue Mar 2 14:05:01 2010 @@ -64,7 +64,6 @@ jl SHORT $LN15 at pypy_g_ll_@139 $LN14 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | 32(%esp)} $LN15 at pypy_g_ll_@139: ; 1529 : l_v420 = l_v419; @@ -76,7 +75,6 @@ test ebx, ebx jne SHORT $LN16 at pypy_g_ll_@139 call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | 32(%esp)} $LN16 at pypy_g_ll_@139: ; 1531 : OP_INT_ADD(l_v402, l_v421, l_v422); @@ -183,7 +181,6 @@ jl SHORT $LN10 at pypy_g_ll_@139 $LN9 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN10 at pypy_g_ll_@139: ; 1517 : l_v413 = l_v412; @@ -195,7 +192,6 @@ test edi, edi jne SHORT $LN11 at pypy_g_ll_@139 call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN11 at pypy_g_ll_@139: mov edi, DWORD PTR [edi+8] @@ -208,7 +204,6 @@ jl SHORT $LN13 at pypy_g_ll_@139 $LN12 at pypy_g_ll_@139: call _RPyAbort - ;; expected {24(%esp) | 12(%esp), 4(%esp), (%esp), 8(%esp) | } $LN13 at pypy_g_ll_@139: ; 1520 : pypy_g_copy_string_contents__rpy_stringPtr_rpy_stringPt(l_v415, l_result_2, 0L, l_res_index_0, l_v414); Modified: pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py Tue Mar 2 14:05:01 2010 @@ -169,6 +169,9 @@ assert len(seen) == len(tabledict), ( "computed table contains unexpected entries:\n%r" % [key for key in tabledict if key not in seen]) - print lines - print expectedlines + print '--------------- got ---------------' + print ''.join(lines) + print '------------- expected ------------' + print ''.join(expectedlines) + print '-----------------------------------' assert lines == expectedlines Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Tue Mar 2 14:05:01 2010 @@ -43,7 +43,8 @@ self.findlabels() self.parse_instructions() try: - if not self.list_call_insns(): + self.find_noncollecting_calls() + if not self.list_collecting_call_insns(): return [] self.findframesize() self.fixlocalvars() @@ -62,7 +63,7 @@ See format_callshape() for more details about callshape_tuple. """ table = [] - for insn in self.list_call_insns(): + for insn in self.list_collecting_call_insns(): if not hasattr(insn, 'framesize'): continue # calls that never end up reaching a RET if self.is_stack_bottom: @@ -81,10 +82,11 @@ if isinstance(localvar, LocalVar): loc = localvar.getlocation(insn.framesize, self.uses_frame_pointer) - else: - assert localvar in self.REG2LOC, "%s: %s" % (self.funcname, - localvar) + elif localvar in self.REG2LOC: loc = self.REG2LOC[localvar] + else: + assert False, "%s: %s" % (self.funcname, + localvar) assert isinstance(loc, int) if tag is None: gcroots.append(loc) @@ -116,6 +118,20 @@ assert label not in self.labels, "duplicate label: %s" % label self.labels[label] = Label(label, lineno) + def find_noncollecting_calls(self): + cannot_collect = self.CANNOT_COLLECT.copy() + for line in self.lines: + match = self.r_gcnocollect_marker.search(line) + if match: + name = match.group(1) + cannot_collect[name] = True + # + if self.format in ('darwin', 'mingw32', 'msvc'): + self.cannot_collect = dict.fromkeys( + ['_' + name for name in cannot_collect]) + else: + self.cannot_collect = cannot_collect + def append_instruction(self, insn): # Add the instruction to the list, and link it to the previous one. previnsn = self.insns[-1] @@ -179,8 +195,9 @@ raise UnrecognizedOperation(opname) setattr(cls, 'visit_' + opname, cls.visit_nop) - def list_call_insns(self): - return [insn for insn in self.insns if isinstance(insn, InsnCall)] + def list_collecting_call_insns(self): + return [insn for insn in self.insns if isinstance(insn, InsnCall) + if insn.name not in self.cannot_collect] def findframesize(self): # the 'framesize' attached to an instruction is the number of bytes @@ -292,7 +309,7 @@ # walk backwards, because inserting the global labels in self.lines # is going to invalidate the lineno of all the InsnCall objects # after the current one. - for call in self.list_call_insns()[::-1]: + for call in self.list_collecting_call_insns()[::-1]: if hasattr(call, 'framesize'): self.create_global_label(call) @@ -334,6 +351,12 @@ # ____________________________________________________________ + CANNOT_COLLECT = { # some of the most used functions that cannot collect + 'pypy_debug_catch_fatal_exception': None, + 'RPyAbort': None, + 'RPyAssertFailed': None, + } + def _visit_gcroot_marker(self, line): match = self.r_gcroot_marker.match(line) loc = match.group(1) @@ -641,7 +664,7 @@ if match is None: assert self.r_unaryinsn_star.match(line) # indirect call - return [InsnCall(self.currentlineno), + return [InsnCall('', self.currentlineno), InsnSetLocal(self.EAX)] # the result is there target = match.group(1) @@ -691,7 +714,7 @@ assert lineoffset in (1,2) return [InsnStackAdjust(-4)] - insns = [InsnCall(self.currentlineno), + insns = [InsnCall(target, self.currentlineno), InsnSetLocal(self.EAX)] # the result is there if self.format in ('mingw32', 'msvc'): # handle __stdcall calling convention: @@ -737,6 +760,7 @@ r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text|\t\.align|"+LABEL) r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+LOCALVARFP+") [*]/") + r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+OPERAND+") [*]/") r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/") FUNCTIONS_NOT_RETURNING = { @@ -813,6 +837,7 @@ r_gcroot_marker = re.compile(r"$1") # never matches r_gcroot_marker_var = re.compile(r"DWORD PTR .+_constant_always_one_.+pypy_asm_gcroot") + r_gcnocollect_marker = re.compile(r"\spypy_asm_gc_nocollect\(("+OPERAND+")\);") r_bottom_marker = re.compile(r"; .+\tpypy_asm_stack_bottom\(\);") FUNCTIONS_NOT_RETURNING = { @@ -864,10 +889,21 @@ 'visit_' + name + 'l') visit_int = FunctionGcRootTracker.visit_nop - visit_npad = FunctionGcRootTracker.visit_nop # probably not GC pointers visit_cdq = FunctionGcRootTracker.visit_nop + def visit_npad(self, line): + # MASM has a nasty bug: it implements "npad 5" with "add eax, 0" + # which is a not no-op because it clears flags. + # I've seen this instruction appear between "test" and "jne"... + # see http://www.masm32.com/board/index.php?topic=13122 + match = self.r_unaryinsn.match(line) + arg = match.group(1) + if arg == "5": + # replace with "npad 3; npad 2" + self.lines[self.currentlineno] = "\tnpad\t3\n" "\tnpad\t2\n" + return [] + def extract_immediate(self, value): try: return int(value) @@ -1183,229 +1219,209 @@ def dump(self, output): assert self.seen_main - shapes = {} - shapelines = [] - shapeofs = 0 + def _globalname(name, disp=""): if self.format in ('darwin', 'mingw32', 'msvc'): name = '_' + name + return name - if self.format == 'msvc': - if disp: - return "DWORD PTR [%s+%s]" % (name, disp) - else: - return name - else: - if disp: - return "%s + %s" % (name, disp) - else: - return name - - def _globl(name): - if self.format == 'msvc': - print >> output, "PUBLIC %s" % _globalname(name) - else: - print >> output, "\t.globl %s" % _globalname(name) - def _label(name): - print >> output, "%s:" % _globalname(name) def _variant(**kwargs): txt = kwargs[self.format] print >> output, "\t%s" % txt - def _comment(comment): - if self.format == 'msvc': - print >> output, "; %s" % comment - else: - print >> output, "/* %s */" % comment - - def _movl(source, target, comment): - if self.format == 'msvc': - print >> output, "\tmov\t%s, %s\t\t; %s" % (target, source, comment) - else: - print >> output, "\tmovl\t%s, %s\t\t/* %s */ " % (source, target, comment) - - def _pushl(source, comment): - if self.format == 'msvc': - print >> output, "\tpush\t%s\t\t; %s" % (source, comment) - else: - print >> output, "\tpushl\t%s\t\t/* %s */ " % (source, comment) - - def _popl(source, comment): - if self.format == 'msvc': - print >> output, "\tpop\t%s\t\t; %s" % (source, comment) - else: - print >> output, "\tpopl\t%s\t\t/* %s */ " % (source, comment) - - - def _register(name, disp=""): - if self.format == 'msvc': - if disp: - return "DWORD PTR [%s+%s]" % (name, disp) - else: - return name - else: - if disp: - return "%s(%%%s)" % (disp, name) - else: - return '%' + name - - def _offset(name): - if self.format == 'msvc': - return "OFFSET %s" % _globalname(name) - else: - return "$%s" % _globalname(name) - - def _call(arg, comment): - if self.format == 'msvc': - print >> output, "\tcall\t%s\t\t;%s" % (arg, comment) - else: - print >> output, "\tcall\t%s\t\t/* %s */" % (arg, comment) - - def _indirectjmp(arg): - if self.format == 'msvc': - return "DWORD PTR " + arg - else: - return "*%" + arg + # The pypy_asm_stackwalk() function if self.format == 'msvc': print >> output, """\ - TITLE\tgcmaptable.s - .686P - .XMM - .model\tflat + /* A circular doubly-linked list of all + * the ASM_FRAMEDATAs currently alive + */ + struct asm_framedata { + struct asm_framedata* prev; + struct asm_framedata* next; + } __gcrootanchor = { &__gcrootanchor, &__gcrootanchor }; + + /* See description in asmgcroot.py */ + __declspec(naked) + long pypy_asm_stackwalk(void *callback) + { + __asm { + mov\tedx, DWORD PTR [esp+4]\t; my argument, which is the callback + mov\teax, esp\t\t; my frame top address + push\teax\t\t\t; ASM_FRAMEDATA[6] + push\tebp\t\t\t; ASM_FRAMEDATA[5] + push\tedi\t\t\t; ASM_FRAMEDATA[4] + push\tesi\t\t\t; ASM_FRAMEDATA[3] + push\tebx\t\t\t; ASM_FRAMEDATA[2] + + ; Add this ASM_FRAMEDATA to the front of the circular linked + ; list. Let's call it 'self'. + + mov\teax, DWORD PTR [__gcrootanchor+4]\t\t; next = gcrootanchor->next + push\teax\t\t\t\t\t\t\t\t\t; self->next = next + push\tOFFSET __gcrootanchor ; self->prev = gcrootanchor + mov\tDWORD PTR [__gcrootanchor+4], esp\t\t; gcrootanchor->next = self + mov\tDWORD PTR [eax+0], esp\t\t\t\t\t; next->prev = self + + call\tedx\t\t\t\t\t\t; invoke the callback + + ; Detach this ASM_FRAMEDATA from the circular linked list + pop\tesi\t\t\t\t\t\t\t; prev = self->prev + pop\tedi\t\t\t\t\t\t\t; next = self->next + mov\tDWORD PTR [esi+4], edi\t\t; prev->next = next + mov\tDWORD PTR [edi+0], esi\t\t; next->prev = prev + + pop\tebx\t\t\t\t; restore from ASM_FRAMEDATA[2] + pop\tesi\t\t\t\t; restore from ASM_FRAMEDATA[3] + pop\tedi\t\t\t\t; restore from ASM_FRAMEDATA[4] + pop\tebp\t\t\t\t; restore from ASM_FRAMEDATA[5] + pop\tecx\t\t\t\t; ignored ASM_FRAMEDATA[6] + ; the return value is the one of the 'call' above, + ; because %eax (and possibly %edx) are unmodified + ret + } + } """ - _variant(elf='\t.text', - darwin='\t.text', - mingw32='\t.text', - msvc='_TEXT\tSEGMENT') - - _globl('pypy_asm_stackwalk') - _variant(elf='.type pypy_asm_stackwalk, @function', - darwin='', - mingw32='', - msvc='') - _label('pypy_asm_stackwalk') - _comment("See description in asmgcroot.py") - _movl(_register("esp", disp="4"), _register("edx"), "my argument, which is the callback") - _movl(_register("esp"), _register("eax"), "my frame top address") - _pushl(_register("eax"), "ASM_FRAMEDATA[6]") - _pushl(_register("ebp"), "ASM_FRAMEDATA[5]") - _pushl(_register("edi"), "ASM_FRAMEDATA[4]") - _pushl(_register("esi"), "ASM_FRAMEDATA[3]") - _pushl(_register("ebx"), "ASM_FRAMEDATA[2]") - - print >> output - _comment("Add this ASM_FRAMEDATA to the front of the circular linked") - _comment("list. Let's call it 'self'.") - print >> output - _movl(_globalname("__gcrootanchor", disp=4), _register("eax"), "next = gcrootanchor->next") - _pushl(_register("eax"), "self->next = next") - _pushl(_offset("__gcrootanchor"), "self->prev = gcrootanchor") - _movl(_register("esp"), _globalname("__gcrootanchor", disp=4), "gcrootanchor->next = self") - _movl(_register("esp"), _register("eax", "0"), "next->prev = self") - print >> output - - _comment("note: the Mac OS X 16 bytes aligment must be respected.") - _call(_indirectjmp("edx"), "invoke the callback") - print >> output - - _comment("Detach this ASM_FRAMEDATA from the circular linked list") - _popl(_register("esi"), "prev = self->prev") - _popl(_register("edi"), "next = self->next") - _movl(_register("edi"), _register("esi", disp="4"), "prev->next = next") - _movl(_register("esi"), _register("edi", disp="0"), "next->prev = prev") - print >> output - - _popl(_register("ebx"), "restore from ASM_FRAMEDATA[2]") - _popl(_register("esi"), "restore from ASM_FRAMEDATA[3]") - _popl(_register("edi"), "restore from ASM_FRAMEDATA[4]") - _popl(_register("ebp"), "restore from ASM_FRAMEDATA[5]") - _popl(_register("ecx"), "ignored ASM_FRAMEDATA[6]") - _comment("the return value is the one of the 'call' above,") - _comment("because %eax (and possibly %edx) are unmodified") - - print >> output, "\tret" - - _variant(elf='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk', - darwin='', - mingw32='', - msvc='') - - if self.format == 'msvc': - for label, state, is_range in self.gcmaptable: - print >> output, "EXTERN %s:NEAR" % label + else: + print >> output, "\t.text" + print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk') + _variant(elf='.type pypy_asm_stackwalk, @function', + darwin='', + mingw32='') + print >> output, "%s:" % _globalname('pypy_asm_stackwalk') - if self.format == 'msvc': - print >> output, '_DATA SEGMENT' + print >> output, """\ + /* See description in asmgcroot.py */ + movl\t4(%esp), %edx\t/* my argument, which is the callback */ + movl\t%esp, %eax\t/* my frame top address */ + pushl\t%eax\t\t/* ASM_FRAMEDATA[6] */ + pushl\t%ebp\t\t/* ASM_FRAMEDATA[5] */ + pushl\t%edi\t\t/* ASM_FRAMEDATA[4] */ + pushl\t%esi\t\t/* ASM_FRAMEDATA[3] */ + pushl\t%ebx\t\t/* ASM_FRAMEDATA[2] */ + + /* Add this ASM_FRAMEDATA to the front of the circular linked */ + /* list. Let's call it 'self'. */ + + movl\t__gcrootanchor + 4, %eax\t/* next = gcrootanchor->next */ + pushl\t%eax\t\t\t\t/* self->next = next */ + pushl\t$__gcrootanchor\t\t\t/* self->prev = gcrootanchor */ + movl\t%esp, __gcrootanchor + 4\t/* gcrootanchor->next = self */ + movl\t%esp, 0(%eax)\t\t\t/* next->prev = self */ + + /* note: the Mac OS X 16 bytes aligment must be respected. */ + call\t*%edx\t\t/* invoke the callback */ + + /* Detach this ASM_FRAMEDATA from the circular linked list */ + popl\t%esi\t\t/* prev = self->prev */ + popl\t%edi\t\t/* next = self->next */ + movl\t%edi, 4(%esi)\t/* prev->next = next */ + movl\t%esi, 0(%edi)\t/* next->prev = prev */ + + popl\t%ebx\t\t/* restore from ASM_FRAMEDATA[2] */ + popl\t%esi\t\t/* restore from ASM_FRAMEDATA[3] */ + popl\t%edi\t\t/* restore from ASM_FRAMEDATA[4] */ + popl\t%ebp\t\t/* restore from ASM_FRAMEDATA[5] */ + popl\t%ecx\t\t/* ignored ASM_FRAMEDATA[6] */ + + /* the return value is the one of the 'call' above, */ + /* because %eax (and possibly %edx) are unmodified */ + ret + """.replace("__gcrootanchor", _globalname("__gcrootanchor")) + + _variant(elf='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk', + darwin='', + mingw32='') - _comment("A circular doubly-linked list of all") - _comment("the ASM_FRAMEDATAs currently alive") if self.format == 'msvc': - _globl('__gcrootanchor') - print >> output, '%s\tDD FLAT:___gcrootanchor ; prev' % _globalname("__gcrootanchor") - print >> output, '\tDD FLAT:___gcrootanchor ; next' - else: - print >> output, '\t.data' - print >> output, '\t.align\t4' - _globl('__gcrootanchor') - _label('__gcrootanchor') + for label, state, is_range in self.gcmaptable: + label = label[1:] + print >> output, "extern void* %s;" % label + else: print >> output, """\ + /* A circular doubly-linked list of all */ + /* the ASM_FRAMEDATAs currently alive */ + .data + .align 4 + .globl __gcrootanchor + __gcrootanchor: .long\t__gcrootanchor /* prev */ .long\t__gcrootanchor /* next */ -""".replace("__gcrootanchor", _globalname("__gcrootanchor")) + """.replace("__gcrootanchor", _globalname("__gcrootanchor")) + + shapes = {} + shapelines = [] + shapeofs = 0 + + # write the tables - _globl('__gcmapstart') if self.format == 'msvc': - print >> output, '%s' % _globalname('__gcmapstart'), + print >> output, """\ + static struct { void* addr; long shape; } __gcmap[%d] = { + """ % (len(self.gcmaptable),) + for label, state, is_range in self.gcmaptable: + label = label[1:] + try: + n = shapes[state] + except KeyError: + n = shapes[state] = shapeofs + bytes = [str(b) for b in compress_callshape(state)] + shapelines.append('\t%s,\t/* %s */\n' % ( + ', '.join(bytes), + shapeofs)) + shapeofs += len(bytes) + if is_range: + n = ~ n + print >> output, '{ &%s, %d},' % (label, n) + print >> output, """\ + }; + void* __gcmapstart = __gcmap; + void* __gcmapend = __gcmap + %d; + + char __gccallshapes[] = { + """ % (len(self.gcmaptable),) + output.writelines(shapelines) + print >> output, """\ + }; + """ else: - _label('__gcmapstart') - for label, state, is_range in self.gcmaptable: - try: - n = shapes[state] - except KeyError: - n = shapes[state] = shapeofs - bytes = [str(b) for b in compress_callshape(state)] - if self.format == 'msvc': - shapelines.append('\tDB\t%s\t;%s\n' % ( - ', '.join(bytes), - shapeofs)) - else: + print >> output, """\ + .globl __gcmapstart + __gcmapstart: + """.replace("__gcmapstart", _globalname("__gcmapstart")) + + for label, state, is_range in self.gcmaptable: + try: + n = shapes[state] + except KeyError: + n = shapes[state] = shapeofs + bytes = [str(b) for b in compress_callshape(state)] shapelines.append('\t/*%d*/\t.byte\t%s\n' % ( shapeofs, ', '.join(bytes))) - shapeofs += len(bytes) - if is_range: - n = ~ n - if self.format == 'msvc': - print >> output, '\tDD\t%s' % (label,) - print >> output, '\tDD\t%d' % (n,) - else: + shapeofs += len(bytes) + if is_range: + n = ~ n print >> output, '\t.long\t%s-%d' % ( label, PARSERS[self.format].FunctionGcRootTracker.OFFSET_LABELS) print >> output, '\t.long\t%d' % (n,) - _globl('__gcmapend') - if self.format == 'msvc': - print >> output, '%s DD ?' % _globalname('__gcmapend') - else: - _label('__gcmapend') - _variant(elf='.section\t.rodata', - darwin='.const', - mingw32='', - msvc='') - - _globl('__gccallshapes') - if self.format == 'msvc': - print >> output, _globalname('__gccallshapes'), - else: - _label('__gccallshapes') - output.writelines(shapelines) + print >> output, """\ + .globl __gcmapend + __gcmapend: + """.replace("__gcmapend", _globalname("__gcmapend")) + + _variant(elf='.section\t.rodata', + darwin='.const', + mingw32='') - if self.format == 'msvc': - print >> output, "_DATA\tENDS" - print >> output, "END" + print >> output, """\ + .globl __gccallshapes + __gccallshapes: + """.replace("__gccallshapes", _globalname("__gccallshapes")) + output.writelines(shapelines) def process(self, iterlines, newfile, entrypoint='main', filename='?'): parser = PARSERS[format](verbose=self.verbose, shuffle=self.shuffle) Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Tue Mar 2 14:05:01 2010 @@ -532,7 +532,7 @@ ['$(CC) /nologo $(ASM_CFLAGS) /c /FAs /Fa$*.s $< $(INCLUDEDIRS)', 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -fmsvc -t $*.s > $@'] ) - mk.rule('gcmaptable.s', '$(GCMAPFILES)', + mk.rule('gcmaptable.c', '$(GCMAPFILES)', 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -fmsvc $(GCMAPFILES) > $@') else: Modified: pypy/trunk/pypy/translator/c/src/mem.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/mem.h (original) +++ pypy/trunk/pypy/translator/c/src/mem.h Tue Mar 2 14:05:01 2010 @@ -2,6 +2,7 @@ /************************************************************/ /*** C header subsection: operations on LowLevelTypes ***/ +#ifndef _MSC_VER extern char __gcmapstart; extern char __gcmapend; extern char __gccallshapes; @@ -18,7 +19,6 @@ and one in a register), pass one to GCROOT, and later use the other one. In practice the pypy_asm_gcroot() is often a no-op in the final machine code and doesn't prevent most optimizations. */ -#ifndef _MSC_VER /* With gcc, getting the asm() right was tricky, though. The asm() is not volatile so that gcc is free to delete it if the output variable @@ -34,13 +34,28 @@ "0" (p), "m" (__gcnoreorderhack)); \ _r; }) +#define pypy_asm_gc_nocollect(f) asm volatile ("/* GC_NOCOLLECT " #f " */" \ + : : ) + #define pypy_asm_keepalive(v) asm volatile ("/* keepalive %0 */" : : \ "g" (v)) /* marker for trackgcroot.py */ #define pypy_asm_stack_bottom() asm volatile ("/* GC_STACK_BOTTOM */" : : ) +#define OP_GC_ASMGCROOT_STATIC(i, r) r = \ + i == 0 ? (void*)&__gcmapstart : \ + i == 1 ? (void*)&__gcmapend : \ + i == 2 ? (void*)&__gccallshapes : \ + i == 3 ? (void*)&__gcrootanchor : \ + NULL + #else +extern void* __gcmapstart; +extern void* __gcmapend; +extern char* __gccallshapes; +extern void* __gcrootanchor; +extern long pypy_asm_stackwalk(void*); /* With the msvc Microsoft Compiler, the optimizer seems free to move any code (even asm) that involves local memory (registers and stack). @@ -58,20 +73,22 @@ return _r1; } +#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */" + #define pypy_asm_keepalive(v) __asm { } static __declspec(noinline) void pypy_asm_stack_bottom() { } -#endif - - - #define OP_GC_ASMGCROOT_STATIC(i, r) r = \ - i == 0 ? (void*)&__gcmapstart : \ - i == 1 ? (void*)&__gcmapend : \ + i == 0 ? (void*)__gcmapstart : \ + i == 1 ? (void*)__gcmapend : \ i == 2 ? (void*)&__gccallshapes : \ i == 3 ? (void*)&__gcrootanchor : \ NULL +#endif + + + #define RAW_MALLOC_ZERO_FILLED 0 #if RAW_MALLOC_ZERO_FILLED From arigo at codespeak.net Tue Mar 2 14:08:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:08:46 +0100 (CET) Subject: [pypy-svn] r71630 - pypy/trunk/pypy/module/sys Message-ID: <20100302130846.D094C282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:08:45 2010 New Revision: 71630 Modified: pypy/trunk/pypy/module/sys/version.py Log: Bump the version number of PyPy. Modified: pypy/trunk/pypy/module/sys/version.py ============================================================================== --- pypy/trunk/pypy/module/sys/version.py (original) +++ pypy/trunk/pypy/module/sys/version.py Tue Mar 2 14:08:45 2010 @@ -7,7 +7,7 @@ CPYTHON_VERSION = (2, 5, 2, "beta", 42) CPYTHON_API_VERSION = 1012 -PYPY_VERSION = (1, 1, 0, "beta", '?') +PYPY_VERSION = (1, 2, 0, "beta", '?') # the last item is replaced by the svn revision ^^^ TRIM_URL_UP_TO = 'svn/pypy/' From arigo at codespeak.net Tue Mar 2 14:09:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:09:00 +0100 (CET) Subject: [pypy-svn] r71631 - pypy/release/1.2.x Message-ID: <20100302130900.0D9A1282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:08:58 2010 New Revision: 71631 Added: pypy/release/1.2.x/ - copied from r71630, pypy/trunk/ Log: Make a release branch. From arigo at codespeak.net Tue Mar 2 14:27:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:27:26 +0100 (CET) Subject: [pypy-svn] r71632 - pypy/trunk/pypy/doc/tool Message-ID: <20100302132726.2705E282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:27:23 2010 New Revision: 71632 Modified: pypy/trunk/pypy/doc/tool/makecontributor.py Log: Actually exclude the authors that want to be excluded :-/ Modified: pypy/trunk/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/trunk/pypy/doc/tool/makecontributor.py (original) +++ pypy/trunk/pypy/doc/tool/makecontributor.py Tue Mar 2 14:27:23 2010 @@ -8,12 +8,12 @@ try: path = py.std.sys.argv[1] except IndexError: - print "usage: %s PATH" %(py.std.sys.argv[0]) + print "usage: %s ROOTPATH" %(py.std.sys.argv[0]) raise SystemExit, 1 d = {} -for logentry in py.path.svnwc(py.std.sys.argv[1]).log(): +for logentry in py.path.svnwc(path).log(): a = logentry.author if a in d: d[a] += 1 @@ -30,6 +30,8 @@ cutoff = 5 # cutoff for authors in the LICENSE file mark = False for author, count in items: + if author in excluded: + continue user = uconf.system.User(author) try: realname = user.realname.strip() From arigo at codespeak.net Tue Mar 2 14:31:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:31:05 +0100 (CET) Subject: [pypy-svn] r71633 - pypy/trunk/pypy/doc Message-ID: <20100302133105.EAB45282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:31:04 2010 New Revision: 71633 Modified: pypy/trunk/pypy/doc/contributor.txt Log: Update the list of contributors. Modified: pypy/trunk/pypy/doc/contributor.txt ============================================================================== --- pypy/trunk/pypy/doc/contributor.txt (original) +++ pypy/trunk/pypy/doc/contributor.txt Tue Mar 2 14:31:04 2010 @@ -8,18 +8,18 @@ Armin Rigo - Samuele Pedroni - Carl Friedrich Bolz Maciek Fijalkowski - Michael Hudson + Carl Friedrich Bolz + Samuele Pedroni Antonio Cuni + Michael Hudson Christian Tismer Holger Krekel Eric van Riet Paap Richard Emslie Anders Chrigstrom - Aurelien Campeas Amaury Forgeot d Arc + Aurelien Campeas Anders Lehmann Niklaus Haldimann Seo Sanghyeon @@ -27,11 +27,12 @@ Lawrence Oluyede Jakub Gustak Guido Wesdorp - Niko Matsakis - Toon Verwaest + Benjamin Peterson Alexander Schremmer + Niko Matsakis Ludovic Aubry Alex Martelli + Toon Verwaest Stephan Diehl Adrien Di Mascio Stefan Schwarzer @@ -39,8 +40,8 @@ Patrick Maupin Jacob Hallen Laura Creighton - Camillo Bruni Bob Ippolito + Camillo Bruni Simon Burton Bruno Gola Alexandre Fayolle @@ -48,46 +49,46 @@ Guido van Rossum Valentino Volonghi Adrian Kuhn - Anders Hammarquist Paul deGrandis Gerald Klix Wanja Saatkamp + Anders Hammarquist Oscar Nierstrasz Eugene Oden Lukas Renggli - Bartosz SKOWRON Guenter Jantzen Dinu Gherman + Bartosz SKOWRON Georg Brandl Ben Young - Nicolas Chauvat Jean-Paul Calderone + Nicolas Chauvat Rocco Moretti Michael Twomey - Boris Feigin + boria Jared Grubb Olivier Dormond Stuart Williams Jens-Uwe Mager Justas Sadzevicius + Mikael Sch?nenberg Brian Dorsey Jonathan David Riehl Beatrice During Elmo M?ntynen Andreas Friedge + Alex Gaynor Anders Qvist Alan McIntyre Bert Freudenberg Pieter Zieschang - Ignas Mikalajunas Jacob Oscarson Lutz Paelike - Benjamin Peterson Michael Schneider Artur Lisiecki Lene Wagner Christopher Armstrong - Joshua Gilbert + Jan de Mooij Jacek Generowicz Gasper Zejn Stephan Busemann @@ -95,11 +96,10 @@ Godefroid Chappelle Toby Watson Andrew Thompson - Gintautas Miliauskas + Joshua Gilbert Anders Sigfridsson - Neil Shepperd + David Schneider Michael Chermside tav - Igor Trindade Oliveira Martin Blais Victor Stinner From arigo at codespeak.net Tue Mar 2 14:37:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:37:02 +0100 (CET) Subject: [pypy-svn] r71634 - pypy/trunk Message-ID: <20100302133702.33BF0282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:36:59 2010 New Revision: 71634 Modified: pypy/trunk/LICENSE Log: Update LICENSE. Modified: pypy/trunk/LICENSE ============================================================================== --- pypy/trunk/LICENSE (original) +++ pypy/trunk/LICENSE Tue Mar 2 14:36:59 2010 @@ -35,18 +35,18 @@ copyrighted by one or more of the following people and organizations: Armin Rigo - Samuele Pedroni - Carl Friedrich Bolz Maciek Fijalkowski - Michael Hudson + Carl Friedrich Bolz + Samuele Pedroni Antonio Cuni + Michael Hudson Christian Tismer Holger Krekel Eric van Riet Paap Richard Emslie Anders Chrigstrom - Aurelien Campeas Amaury Forgeot d Arc + Aurelien Campeas Anders Lehmann Niklaus Haldimann Seo Sanghyeon @@ -54,11 +54,12 @@ Lawrence Oluyede Jakub Gustak Guido Wesdorp - Niko Matsakis - Toon Verwaest + Benjamin Peterson Alexander Schremmer + Niko Matsakis Ludovic Aubry Alex Martelli + Toon Verwaest Stephan Diehl Adrien Di Mascio Stefan Schwarzer @@ -66,8 +67,8 @@ Patrick Maupin Jacob Hallen Laura Creighton - Camillo Bruni Bob Ippolito + Camillo Bruni Simon Burton Bruno Gola Alexandre Fayolle @@ -75,34 +76,35 @@ Guido van Rossum Valentino Volonghi Adrian Kuhn - Anders Hammarquist Paul deGrandis Gerald Klix Wanja Saatkamp + Anders Hammarquist Oscar Nierstrasz Eugene Oden Lukas Renggli - Bartosz SKOWRON Guenter Jantzen Dinu Gherman + Bartosz SKOWRON Georg Brandl - Benjamin Peterson Ben Young - Nicolas Chauvat Jean-Paul Calderone + Nicolas Chauvat Rocco Moretti Michael Twomey - Boris Feigin + boria Jared Grubb Olivier Dormond Stuart Williams Jens-Uwe Mager Justas Sadzevicius + Mikael Sch?nenberg Brian Dorsey Jonathan David Riehl Beatrice During Elmo M?ntynen Andreas Friedge + Alex Gaynor Anders Qvist Alan McIntyre Bert Freudenberg From arigo at codespeak.net Tue Mar 2 14:46:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 14:46:22 +0100 (CET) Subject: [pypy-svn] r71635 - pypy/trunk/pypy/doc Message-ID: <20100302134622.2C143282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 14:46:20 2010 New Revision: 71635 Modified: pypy/trunk/pypy/doc/how-to-release.txt Log: Update how-to-release.txt. Modified: pypy/trunk/pypy/doc/how-to-release.txt ============================================================================== --- pypy/trunk/pypy/doc/how-to-release.txt (original) +++ pypy/trunk/pypy/doc/how-to-release.txt Tue Mar 2 14:46:20 2010 @@ -23,14 +23,14 @@ some of the next updates may be done before or after branching; make sure things are ported back to the trunk and to the branch as necessary -* update dist/pypy/doc/contributor.txt (and possibly dist/LICENSE) -* update dist/README -* write release announcement dist/pypy/doc/release-x.y(.z).txt +* update pypy/doc/contributor.txt (and possibly LICENSE) +* update README +* write release announcement pypy/doc/release-x.y(.z).txt the release announcement should contain a direct link to the download page (which is getting started). -* update dist/pypy/doc/getting-started.txt links at the top +* update pypy/doc/getting-started.txt links at the top and release number references, make sure it is generally up-to-date -* use, after the necessary updates, dist/pypy/tool/makerelease.py to +* use, after the necessary updates, pypy/tool/makerelease.py to make the tarballs on codespeak; this generates html doc for the tarballs too. Use:: @@ -44,6 +44,8 @@ if some stuff is missing. We have some support for running part of our nightly tests on tarballs (see http://codespeak.net/svn/user/pedronis/tarball-testing). -* write a news item for the release in dist/pypy/doc/news.txt +* write a news item for the release in pypy/doc/news.txt +* update http://codespeak.net/svn/pypy/dist and codespeak's + precomputed html files * send announcements to pypy-dev, pypy-funding, python-list, python-announce, python-dev ... From arigo at codespeak.net Tue Mar 2 15:04:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 15:04:50 +0100 (CET) Subject: [pypy-svn] r71636 - pypy/trunk/pypy/doc Message-ID: <20100302140450.80B52282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 15:04:47 2010 New Revision: 71636 Added: pypy/trunk/pypy/doc/release-1.2.0.txt (contents, props changed) Log: Start writing the release announcement. Added: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Tue Mar 2 15:04:47 2010 @@ -0,0 +1,75 @@ +============================================= +PyPy 1.2: Preview of Just-in-Time Compilation +============================================= + +Welcome to the PyPy 1.2 release. The highlight of this release is a +version of PyPy that includes a rather good JIT (Just-in-Time) Compiler. + +Download page: + + http://codespeak.net/pypy/dist/pypy/doc/download.html + +PyPy's Getting Started lives at: + + http://codespeak.net/pypy/dist/pypy/doc/getting-started.html + +Highlights of This Release +========================== + + - JIT. XXX only on 32-bit Intel CPUs so far. + + http://morepypy.blogspot.com/search/label/jit + + - Graphs: + + http://speed.pypy.org/ + http://codespeak.net:8099/plotsummary.html + http://codespeak.net/pypy/jitplots.html + + - Improvements in GC and in our object model: we use much less memory + than CPython now + + http://morepypy.blogspot.com/2009/10/gc-improvements.html + http://? for the object model, e.g. sharingdict.py + + +Other Changes +============= + + - ? + + +What is PyPy? +============= + +Technically, PyPy is both a Python interpreter implementation and an +advanced compiler, or more precisely a framework for implementing dynamic +languages and generating virtual machines for them. + +The framework allows for alternative frontends as well as for alternative +backends, currently C, Java and .NET. For our main target "C", we can +"mix in" different garbage collectors and threading models, +including micro-threads aka "Stackless". The inherent complexity that +arises from this ambitious approach is mostly kept away from the Python +interpreter implementation, our main frontend. + +The focus of this release is the introduction of a new transformation, +the JIT Compiler Generator, which is able to produce a JIT Compiler for +any interpreter frontend, given a very small number of hand-written hints. + +Socially, PyPy is a collaborative effort of many individuals working +together in a distributed and sprint-driven way since 2003. PyPy would +not have gotten as far as it has without the coding, feedback and +general support from numerous people. + + + +Have fun, + + the PyPy release team, [in alphabetical order] + + Amaury Forgeot d'Arc, Antonio Cuni, Armin Rigo, Carl Friedrich Bolz, + Holger Krekel, Maciek Fijalkowski, Samuele Pedroni + + and many others: + http://codespeak.net/pypy/dist/pypy/doc/contributor.html From arigo at codespeak.net Tue Mar 2 15:11:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 15:11:05 +0100 (CET) Subject: [pypy-svn] r71637 - pypy/trunk/pypy/doc Message-ID: <20100302141105.A77A9282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 15:11:04 2010 New Revision: 71637 Modified: pypy/trunk/pypy/doc/download.txt Log: Start updating download.txt. Modified: pypy/trunk/pypy/doc/download.txt ============================================================================== --- pypy/trunk/pypy/doc/download.txt (original) +++ pypy/trunk/pypy/doc/download.txt Tue Mar 2 15:11:04 2010 @@ -2,19 +2,28 @@ Download one of the following release files: ============================================= -PyPy 1.1 Sources: +PyPy 1.2 Sources: ----------------- -* `pypy-1.1.0.tar.bz2`_ (sources, unix line endings) or -* `pypy-1.1.0.tar.gz`_ (sources, unix line endings) or -* `pypy-1.1.0.zip`_ (sources, windows line-endings) - -.. _`pypy-1.1.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.1.0.tar.bz2 -.. _`pypy-1.1.0.zip`: http://codespeak.net/download/pypy/pypy-1.1.0.zip -.. _`pypy-1.1.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.1.0.tar.gz +* `pypy-1.2.0.tar.bz2`_ (sources, unix line endings) or +* `pypy-1.2.0.tar.gz`_ (sources, unix line endings) or +* `pypy-1.2.0.zip`_ (sources, windows line-endings) + +.. _`pypy-1.2.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.bz2 +.. _`pypy-1.2.0.zip`: http://codespeak.net/download/pypy/pypy-1.2.0.zip +.. _`pypy-1.2.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.gz Prebuilt binaries ~~~~~~~~~~~~~~~~~ -We do not provide prebuilt binaries yet (but would happily -link to other people's pages with one version or another). +XXX + +The ``lang`` repository +~~~~~~~~~~~~~~~~~~~~~~~ + +The ``lang`` part of our repository, which contains other interpreters +developped mostly as external contributions, has moved and is no longer +included in the above packages. You can grab it by `browsing the +Subversion source`__. + +.. __: http://codespeak.net/svn/pypy/lang/ From getxsick at codespeak.net Tue Mar 2 15:16:08 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 15:16:08 +0100 (CET) Subject: [pypy-svn] r71638 - in pypy/build/ubuntu/debian: . manpages Message-ID: <20100302141608.DC10D282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 15:16:07 2010 New Revision: 71638 Removed: pypy/build/ubuntu/debian/manpages/pypy-stackless.1 pypy/build/ubuntu/debian/pypy-stackless.install pypy/build/ubuntu/debian/pypy-stackless.manpages Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/configure.py pypy/build/ubuntu/debian/control Log: remove pypy-stackless package Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 15:16:07 2010 @@ -3,13 +3,11 @@ TRANSLATE=pypy/translator/goal/translate.py TRANSLATEOPTS=--text --batch -b c --source --thread TARGETOPTS=%(TARGETOPTS)s -TARGETOPTS_STACKLESS=%(TARGETOPTS_STACKLESS)s PREFIX=%(PREFIX)s OUTPUTDIR=debian/tmp/usr/bin -STACKLESS=--stackless LOGIC=-o logic -BINARIES=bin/pypy bin/pypy-stackless +BINARIES=bin/pypy all: $(BINARIES) @@ -23,14 +21,6 @@ make -C $(TMPDIR)/debian-pypy-usession-0/testing_1 install -D $(TMPDIR)/debian-pypy-usession-0/testing_1/testing_1 $@ -bin/pypy-stackless: export TMPDIR = $(CURDIR)/build-stackless -bin/pypy-stackless: - @rm -rf $(TMPDIR) - mkdir $(TMPDIR) - $(TRANSLATE) $(TRANSLATEOPTS) $(STACKLESS) $(TARGET) $(TARGETOPTS_STACKLESS) - make -C $(TMPDIR)/debian-pypy-usession-0/testing_1 - install -D $(TMPDIR)/debian-pypy-usession-0/testing_1/testing_1 $@ - clean: rm -rf bin rm -rf build-* Modified: pypy/build/ubuntu/debian/configure.py ============================================================================== --- pypy/build/ubuntu/debian/configure.py (original) +++ pypy/build/ubuntu/debian/configure.py Tue Mar 2 15:16:07 2010 @@ -25,17 +25,14 @@ def gen_make(make_in, build_arch, host_arch, prefix): options = {'default': {'TARGETOPTS': '--allworkingmodules', - 'TARGETOPTS_STACKLESS': '--allworkingmodules', 'TARGETOPTS_LOGIC': '--allworkingmodules', }, 'i386': {'TARGETOPTS': '--allworkingmodules --faassen', - 'TARGETOPTS_STACKLESS': '--allworkingmodules --faassen', 'TARGETOPTS_LOGIC': '--allworkingmodules', }, 'amd64':{'TARGETOPTS': '--allworkingmodules --faassen', - 'TARGETOPTS_STACKLESS': '--allworkingmodules', 'TARGETOPTS_LOGIC': '--allworkingmodules', }, } Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Tue Mar 2 15:16:07 2010 @@ -34,18 +34,7 @@ . This package provides the PyPy interpreter compiled using the C backend and no special additionnal functionality. As such it can be used as another - implementation of the Python language. See pypy-stackless for an enhanced - version. - -Package: pypy-stackless -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib -Description: the python in python interpreter, C backend translation - The PyPy project aims to provide a Python implementation of the Python - interpreter. - . - This package provides the PyPy interpreter compiled using the C backend, with - stackless functionality. + implementation of the Python language. Package: pypy-doc Architecture: all From arigo at codespeak.net Tue Mar 2 15:24:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 15:24:40 +0100 (CET) Subject: [pypy-svn] r71639 - pypy/trunk/pypy/doc/jit Message-ID: <20100302142440.ABD31282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 15:24:39 2010 New Revision: 71639 Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt Log: Fix broken url. Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/trunk/pypy/doc/jit/pyjitpl5.txt Tue Mar 2 15:24:39 2010 @@ -172,7 +172,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/ipcoolps2009/bolz-tracing-jit.pdf +.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ From arigo at codespeak.net Tue Mar 2 15:34:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 15:34:42 +0100 (CET) Subject: [pypy-svn] r71640 - pypy/trunk/pypy/doc Message-ID: <20100302143442.5B1B2282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 15:34:40 2010 New Revision: 71640 Modified: pypy/trunk/pypy/doc/architecture.txt pypy/trunk/pypy/doc/faq.txt pypy/trunk/pypy/doc/release-1.2.0.txt Log: Updates. Modified: pypy/trunk/pypy/doc/architecture.txt ============================================================================== --- pypy/trunk/pypy/doc/architecture.txt (original) +++ pypy/trunk/pypy/doc/architecture.txt Tue Mar 2 15:34:40 2010 @@ -250,7 +250,7 @@ .. _`Extreme Programming`: http://www.extremeprogramming.org/ .. _fast: faq.html#how-fast-is-pypy -.. _`very compliant`: http://codespeak.net:8099/summary?category=lib-python&branch=%3Ctrunk%3E +.. _`very compliant`: cpython_differences.html .. _`RPython`: coding-guide.html#rpython Modified: pypy/trunk/pypy/doc/faq.txt ============================================================================== --- pypy/trunk/pypy/doc/faq.txt (original) +++ pypy/trunk/pypy/doc/faq.txt Tue Mar 2 15:34:40 2010 @@ -131,19 +131,25 @@ .. _whysoslow: -The answer to this question depends on how the PyPy interpreter is run. When -optimized and translated to C, the PyPy interpreter runs somewhere between 1 -and 2 times slower than CPython. If the PyPy interpreter is run on top of -CPython, i.e., without translation of any kind, then it is slower by a factor -of 2000. Obtaining good measurements for the performance when run on the CLI or -JVM is difficult, but it is safe to say that PyPy currently runs slower than -IronPython (CLI) or Jython (JVM) for most tests. - -The work on the Just-In-Time compiler is currently at its fifth revision, -but it looks like this revision is finally going to make it. It is work -in progress; see the `JIT documentation`_. +In three words, PyPy is "kind of fast". In more than three +words, the answer to this question is hard to give as a single +number. The fastest PyPy available so far is clearly PyPy +`with a JIT included`_, optimized and translated to C. This +version of PyPy is "kind of fast" in the sense that there are +numerous examples of Python code that run *much faster* than +CPython, up to a large number of times faster. And there are +also examples of code that are just as slow as without the +JIT. A PyPy that does not include a JIT has performance that +is more predictable: it runs generally somewhere between 1 and +2 times slower than CPython, in the worst case up to 4 times +slower. + +Obtaining good measurements for the performance when run on +the CLI or JVM is difficult, but the JIT on the CLI `seems to +work nicely`__ too. -.. _`JIT documentation`: jit/index.html +.. __: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf +.. _`with a JIT included`: jit/index.html .. _`prolog and javascript`: @@ -163,10 +169,11 @@ Currently, we have preliminary versions of a JavaScript interpreter (Leonardo Santagada as his Summer of PyPy project), a `Prolog interpreter`_ (Carl Friedrich Bolz as his Bachelor thesis), and a `SmallTalk interpreter`_ -(produced during a sprint). All of them are unfinished at the moment. +(produced during a sprint). `All of them`_ are unfinished at the moment. .. _`Prolog interpreter`: http://codespeak.net/svn/pypy/lang/prolog/ .. _`SmallTalk interpreter`: http://dx.doi.org/10.1007/978-3-540-89275-5_7 +.. _`All of them`: http://codespeak.net/svn/pypy/lang/ Development ======================================================================== Modified: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- pypy/trunk/pypy/doc/release-1.2.0.txt (original) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Tue Mar 2 15:34:40 2010 @@ -38,6 +38,10 @@ - ? + - CLI+JIT not included in the release + + - Stackless incompatible with the JIT + What is PyPy? ============= From arigo at codespeak.net Tue Mar 2 16:10:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 16:10:37 +0100 (CET) Subject: [pypy-svn] r71641 - pypy/trunk/pypy/doc Message-ID: <20100302151037.BBA67282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 16:10:36 2010 New Revision: 71641 Modified: pypy/trunk/pypy/doc/faq.txt pypy/trunk/pypy/doc/project-ideas.txt Log: Updates. Modified: pypy/trunk/pypy/doc/faq.txt ============================================================================== --- pypy/trunk/pypy/doc/faq.txt (original) +++ pypy/trunk/pypy/doc/faq.txt Tue Mar 2 16:10:36 2010 @@ -56,10 +56,12 @@ OS X and mostly works under Windows too (but is tested there less extensively). PyPy needs a CPython running on the target platform to bootstrap, as cross compilation is not really meant to work yet. -At the moment you need CPython 2.4 (with ctypes 0.9.9.6 or newer) or -CPython 2.5 for the translation process. +At the moment you need CPython 2.4 (with ctypes) or CPython 2.5 or 2.6 +for the translation process. -PyPy also basically works in a 64-bit Linux environment. +PyPy also basically works in a 64-bit Linux environment, but +*it requires a 32-bit Intel CPU* for the JIT right now. (It works +fine in a 32-bit chroot of an Intel 64.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? Modified: pypy/trunk/pypy/doc/project-ideas.txt ============================================================================== --- pypy/trunk/pypy/doc/project-ideas.txt (original) +++ pypy/trunk/pypy/doc/project-ideas.txt Tue Mar 2 16:10:36 2010 @@ -23,35 +23,41 @@ -------------------------------- PyPy's Just-In-Time compiler relies on backends for actual code -generation. Right now we are working on the ``pyjitpl5`` branch, which -is not stable. Working on the JIT backends should be soon possible. -Open ideas are to write a backend for AMD64 (Intel 64); or .NET or -Java (requires porting the JIT frontend to ootype too, which is not too -hard); or trying to use LLVM-JIT. +generation. We have so far a 32-bit Intel backend, and a CLI one. Open +ideas are to write a backend for **Intel 64** (AMD64); or a backend for +Java; or trying again to use LLVM-JIT (which I do not really recommend). CTypes ------ Support ctypes on more backends. Right now ctypes is supported only -when compiling PyPy to C. A nice project would be to support it when +when compiling PyPy to C, and there is a bit of unfinished work to +support it on **Intel 64.** A nice project would be to support it when compiling to .NET or the JVM. That's not too hard, the only thing needed is to port a small module that does the actual invocation of external -libraries (a related project would be to port this module to Jython or -IronPython to get support for ctypes there). +libraries (a related project is to port this module to Jython or +IronPython to get support for ctypes there, which is something that was +tried but not finished as far as I know). .. _distribution: .. _persistence: -Experiment with distribution and persistence --------------------------------------------- +Extensions of the Python language +--------------------------------- + ++----------------------------------------------------------------------+ +| :NOTE: | +| | +| The ideas in this paragraph are marked as "experimental". We may | +| or may not be interested in helping you out. You are warned :-) | +| | ++----------------------------------------------------------------------+ One of the advantages of PyPy's implementation is that the Python-level type of an object and its implementation are completely independent. This should allow a much more intuitive interface to, for example, objects that are backed -by a persistent store. - -The `transparent proxy`_ objects are a key step in this +by a persistent store. The `transparent proxy`_ objects are a key step in this direction; now all that remains is to implement the interesting bits :-) An example project might be to implement functionality akin to the `ZODB's @@ -61,15 +67,22 @@ Another example would be to implement a multi-CPU extension that internally uses several processes and uses transparent proxies to share object views. +Other ideas are to do something interesting with sandboxing_; or to +work more on the Stackless_ features (e.g. integrate it with the JIT); +or revive the logic object space, which tried to bring unification-like +features to Python. + +.. _sandboxing: sandbox.html +.. _Stackless: stackless.html + -Various Ideas -------------- +Other languages +--------------- -- improve one of the existing interpreters (e.g. the Prolog, the Scheme or - the JavaScript interpreter or the Smalltalk VM), or start a new one +Improve one of the `existing interpreters`__, or start a new one. +Experiment with the JIT compiler generator. -- revive the logic object space, which tried to bring unification-like - features to Python +.. __: http://codespeak.net/svn/pypy/lang/ Or else... From arigo at codespeak.net Tue Mar 2 16:11:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 16:11:15 +0100 (CET) Subject: [pypy-svn] r71642 - pypy/trunk/pypy/doc Message-ID: <20100302151115.1812E282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 16:11:13 2010 New Revision: 71642 Modified: pypy/trunk/pypy/doc/project-ideas.txt Log: Updated the list. Modified: pypy/trunk/pypy/doc/project-ideas.txt ============================================================================== --- pypy/trunk/pypy/doc/project-ideas.txt (original) +++ pypy/trunk/pypy/doc/project-ideas.txt Tue Mar 2 16:11:13 2010 @@ -1,8 +1,6 @@ Independent project ideas relating to PyPy ========================================== -*NOTE: This is an extremely outdated list, don't consider it seriously* - PyPy allows experimentation in many directions -- indeed facilitating experimentation in language implementation was one of the main motivations for the project. This page is meant to collect some ideas From arigo at codespeak.net Tue Mar 2 16:33:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 16:33:22 +0100 (CET) Subject: [pypy-svn] r71643 - pypy/trunk/pypy/doc Message-ID: <20100302153322.809E6282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 16:33:20 2010 New Revision: 71643 Modified: pypy/trunk/pypy/doc/getting-started-python.txt pypy/trunk/pypy/doc/getting-started.txt Log: Updates. Modified: pypy/trunk/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started-python.txt (original) +++ pypy/trunk/pypy/doc/getting-started-python.txt Tue Mar 2 16:33:20 2010 @@ -47,34 +47,28 @@ * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) * ``libexpat1-dev`` (for the optional ``pyexpat`` module) * ``libssl-dev`` (for the optional ``_ssl`` module) - * ``libgc-dev`` (only when translating with `--opt=0, 1` or `size`) + * ``libgc-dev`` (Boehm: only when translating with `--opt=0, 1` or `size`) 2. Translation is somewhat time-consuming (30 min to over one hour) and RAM-hungry. If you have less than 1.5 GB of RAM (or a slow machine) you might want to pick the `optimization level`_ `1` in the next step. A level of - `2` or `3` gives much better results, though. + `2` or `3` or `jit` gives much better results, though. Let me stress this another time: at ``--opt=1`` you get the Boehm GC, which is here mostly for historical and for testing reasons. You really do not want to pick it. The resulting ``pypy-c`` is slow. - Alternatively, if you want to enable the experimental JIT, choose - the optimization level ``jit``. - 3. Run:: cd pypy/translator/goal - python translate.py --opt=3 targetpypystandalone.py - - possibly replacing ``--opt=3`` with ``--opt=jit`` or another - `optimization level`_ of your choice. + python translate.py --opt=jit targetpypystandalone.py - On Linux 32-bit Intel machines, you can get some extra speed - (and extra translation time) by adding ``--gcrootfinder=asmgcc`` - just after the ``--opt`` option. (This option is implied by - ``--opt=jit``.) + possibly replacing ``--opt=jit`` with another `optimization level`_ + of your choice like ``--opt=2`` if you do not want the included JIT + compiler. (The default level so far is 2. Do not use ``--opt=jit`` + on something else than Intel **32-bit** machines.) .. _`optimization level`: config/opt.html @@ -99,11 +93,13 @@ >>>> This executable can be moved around or copied on other machines; see -Installation_ below. +Installation_ below. For now a JIT-enabled ``pypy-c`` always produces +debugging output to stderr when it exits, unless translated with +``--jit-debug=off``. The ``translate.py`` script takes a very large number of options controlling what to translate and how. See ``translate.py -h``. Some of the more -interesting options are: +interesting options (but for now incompatible with the JIT) are: * ``--stackless``: this produces a pypy-c that includes features inspired by `Stackless Python `__. @@ -121,54 +117,12 @@ .. _`translate PyPy with the thunk object space`: -Translating with the thunk object space +Translating with non-standard options ++++++++++++++++++++++++++++++++++++++++ -One of the original features provided by PyPy is the "thunk" -object space, providing lazily-computed objects in a fully -transparent manner:: - - cd pypy - python bin/py.py -o thunk - - >>>> from __pypy__ import thunk - >>>> def longcomputation(lst): - .... print "computing..." - .... return sum(lst) - .... - >>>> x = thunk(longcomputation, range(5)) - >>>> y = thunk(longcomputation, range(10)) - -From the application perspective, ``x`` and ``y`` represent -exactly the objects being returned by the ``longcomputation()`` -invocations. You can put these objects into a dictionary -without triggering the computation:: - - >>>> d = {5: x, 10: y} - >>>> result = d[5] - >>>> result - computing... - 10 - >>>> type(d[10]) - computing... - - >>>> d[10] - 45 - -It is interesting to note that this lazy-computing Python extension -is solely implemented in a small `objspace/thunk.py`_ file consisting -of around 200 lines of code. - -It is also possible to translate a PyPy version using the "thunk" object -space:: - - cd pypy/translator/goal - python translate.py targetpypystandalone.py --objspace=thunk - -the example above should work in the translated result. - -If you want know more about pypy-exclusive features go to `objspace proxies`_ -document. +It is possible to have non-standard features enabled for translation, +but they are not really tested any more. Look for example at the +`objspace proxies`_ document. .. _`objspace proxies`: objspace-proxies.html @@ -181,7 +135,15 @@ ./translate.py --backend=cli targetpypystandalone.py -The executable and all its dependecies will be stored in the +Or better, try out the experimental `branch/cli-jit`_ described by +Antonio Cuni's `Ph.D. thesis`_ and translate with the JIT:: + + ./translate.py -Ojit --backend=cli targetpypystandalone.py + +.. _`branch/cli-jit`: http://codespeak.net/svn/pypy/branch/cli-jit/ +.. _`Ph.D. thesis`: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf + +The executable and all its dependencies will be stored in the ./pypy-cli-data directory. To run pypy.NET, you can run ./pypy-cli-data/main.exe. If you are using Linux or Mac, you can use the convenience ./pypy-cli script:: @@ -334,11 +296,6 @@ .. _`CLI backend`: cli-backend.html .. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ .. _clr: clr-module.html -.. _`CPythons core language regression tests`: http://codespeak.net:8099/summary?category=lib-python&branch=%3Ctrunk%3E +.. _`CPythons core language regression tests`: http://codespeak.net:8099/summary?category=applevel&branch=%3Ctrunk%3E .. include:: _ref.txt - - - - - Modified: pypy/trunk/pypy/doc/getting-started.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started.txt (original) +++ pypy/trunk/pypy/doc/getting-started.txt Tue Mar 2 16:33:20 2010 @@ -14,10 +14,9 @@ Python itself, flexible and easy to experiment with. We target a large variety of platforms, small and large, by providing a compiler toolsuite that can produce custom Python versions. Platform, memory -and threading models are aspects of the translation process - as -opposed to encoding low level details into the language implementation itself. -Eventually, dynamic optimization techniques - implemented as another -translation aspect - should become robust against language changes. `more...`_ +and threading models, as well as the JIT compiler itself, are aspects of the +translation process - as opposed to encoding low level details into the +language implementation itself. `more...`_ .. _Python: http://docs.python.org/ref .. _`more...`: architecture.html From getxsick at codespeak.net Tue Mar 2 16:33:59 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 16:33:59 +0100 (CET) Subject: [pypy-svn] r71644 - pypy/build/ubuntu/debian Message-ID: <20100302153359.E347F282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 16:33:58 2010 New Revision: 71644 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/changelog pypy/build/ubuntu/debian/configure.py pypy/build/ubuntu/debian/pypy-dev.install pypy/build/ubuntu/debian/pypy-dev.links pypy/build/ubuntu/debian/pypy-dev.override pypy/build/ubuntu/debian/pypy-lib.install pypy/build/ubuntu/debian/rules Log: update to 1.2 release and merge some changes done by Chris Lamby Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 16:33:58 2010 @@ -1,15 +1,24 @@ TARGET=pypy/translator/goal/targetpypystandalone TRANSLATE=pypy/translator/goal/translate.py -TRANSLATEOPTS=--text --batch -b c --source --thread +TRANSLATEOPTS=--batch --source --Ojit TARGETOPTS=%(TARGETOPTS)s PREFIX=%(PREFIX)s OUTPUTDIR=debian/tmp/usr/bin LOGIC=-o logic -BINARIES=bin/pypy +BINARIES=%(BINARIES)s -all: $(BINARIES) +all: $(BINARIES) test + +test: export TMPDIR = $(CURDIR)/tests-tmp +test: + @rm -rf $(TMPDIR) + mkdir $(TMPDIR) + set -e; for SECTION in interpreter lib; do \ + time py/bin/py.test pypy/$$SECTION || true; \ + echo Finished tsting section $$SECTION; \ + done .NOTPARALLEL: $(BINARIES) @@ -17,13 +26,14 @@ bin/pypy: @rm -rf $(TMPDIR) mkdir $(TMPDIR) - $(TRANSLATE) $(TRANSLATEOPTS) $(TARGET) $(TARGETOPTS) + $(TRANSLATE) $(TRANSLATEOPTS) $(TARGET) $(TARGETOPTS) make -C $(TMPDIR)/debian-pypy-usession-0/testing_1 install -D $(TMPDIR)/debian-pypy-usession-0/testing_1/testing_1 $@ clean: rm -rf bin rm -rf build-* + rm -rf tests-tmp rm -rf pypy/_cache rm -rf py/c-extension/greenlet/build rm -f py/c-extension/greenlet/greenlet.so Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Tue Mar 2 16:33:58 2010 @@ -1,3 +1,26 @@ +pypy (1.2.0-svn71592-1) unstable; urgency=low + + * New upstream release. + * New maintainer. + + -- Bartosz Skowron Mon, 01 Mar 2010 18:30:44 +0100 + +pypy (1.0.0-svn55443-2) unstable; urgency=low + + * Bump MEMTHRESHOLD to 1400MB. + + -- Chris Lamb Sat, 21 Jun 2008 21:42:09 +0100 + +pypy (1.0.0-svn55443-1) unstable; urgency=low + + * New upstream snapshot. + - Doesn't hardcode libc6.so.6; fixes FTBFS on ia64 (Closes: #440331) + * Don't build pypy-stackless on platforms the greenlet module has not been + ported to. (Closes: #475868) + * Run tests after build on request by upstream. + + -- Chris Lamb Sat, 31 May 2008 18:50:58 +0100 + pypy (1.0.0-svn51288-1) unstable; urgency=low * New upstream release. (Closes: #459118) Modified: pypy/build/ubuntu/debian/configure.py ============================================================================== --- pypy/build/ubuntu/debian/configure.py (original) +++ pypy/build/ubuntu/debian/configure.py Tue Mar 2 16:33:58 2010 @@ -2,7 +2,7 @@ import sys import os -MEMTHRESHOLD = 1024 +MEMTHRESHOLD = 1400 LOWMEM = """\ The translation of pypy requires a large amount of physical @@ -24,20 +24,15 @@ def gen_make(make_in, build_arch, host_arch, prefix): - options = {'default': {'TARGETOPTS': '--allworkingmodules', - 'TARGETOPTS_LOGIC': '--allworkingmodules', - }, - - 'i386': {'TARGETOPTS': '--allworkingmodules --faassen', - 'TARGETOPTS_LOGIC': '--allworkingmodules', - }, - - 'amd64':{'TARGETOPTS': '--allworkingmodules --faassen', - 'TARGETOPTS_LOGIC': '--allworkingmodules', - }, - } - substitutions = options.get(build_arch, options['default']) - substitutions['PREFIX'] = prefix + default = {'TARGETOPTS': '--allworkingmodules', + 'TARGETOPTS_LOGIC': '--allworkingmodules', + 'BINARIES': 'bin/pypy', + } + options = {} + #options['i386'] = {'TARGETOPTS': '--allworkingmodules -Ojit'} + + substitutions = dict(PREFIX=prefix, **default) + substitutions.update(options.get(build_arch, {})) return make_in % substitutions def run(): Modified: pypy/build/ubuntu/debian/pypy-dev.install ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.install (original) +++ pypy/build/ubuntu/debian/pypy-dev.install Tue Mar 2 16:33:58 2010 @@ -1,17 +1,17 @@ -pypy/annotation usr/share/pypy-1.0/pypy -pypy/bin usr/share/pypy-1.0/pypy -pypy/config usr/share/pypy-1.0/pypy -pypy/__init__.py usr/share/pypy-1.0/pypy -pypy/interpreter usr/share/pypy-1.0/pypy -pypy/jit usr/share/pypy-1.0/pypy -pypy/lang usr/share/pypy-1.0/pypy -pypy/module usr/share/pypy-1.0/pypy -pypy/objspace usr/share/pypy-1.0/pypy -pypy/rlib usr/share/pypy-1.0/pypy -pypy/rpython usr/share/pypy-1.0/pypy -pypy/tool usr/share/pypy-1.0/pypy -pypy/translator usr/share/pypy-1.0/pypy -pypy/conftest.py usr/share/pypy-1.0/pypy +pypy/annotation usr/share/pypy-1.2/pypy +pypy/bin usr/share/pypy-1.2/pypy +pypy/config usr/share/pypy-1.2/pypy +pypy/__init__.py usr/share/pypy-1.2/pypy +pypy/interpreter usr/share/pypy-1.2/pypy +pypy/jit usr/share/pypy-1.2/pypy +pypy/lang usr/share/pypy-1.2/pypy +pypy/module usr/share/pypy-1.2/pypy +pypy/objspace usr/share/pypy-1.2/pypy +pypy/rlib usr/share/pypy-1.2/pypy +pypy/rpython usr/share/pypy-1.2/pypy +pypy/tool usr/share/pypy-1.2/pypy +pypy/translator usr/share/pypy-1.2/pypy +pypy/conftest.py usr/share/pypy-1.2/pypy debian/scripts/py.py usr/bin debian/scripts/pypy-translate usr/bin debian/scripts/jscompile usr/bin Modified: pypy/build/ubuntu/debian/pypy-dev.links ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.links (original) +++ pypy/build/ubuntu/debian/pypy-dev.links Tue Mar 2 16:33:58 2010 @@ -1 +1 @@ -/var/cache/pypy/_cache /usr/share/pypy-1.0/pypy/_cache +/var/cache/pypy/_cache /usr/share/pypy-1.2/pypy/_cache Modified: pypy/build/ubuntu/debian/pypy-dev.override ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.override (original) +++ pypy/build/ubuntu/debian/pypy-dev.override Tue Mar 2 16:33:58 2010 @@ -1,5 +1,5 @@ # Gentoo specific file. We will keep it. -pypy-dev: unusual-interpreter ./usr/share/pypy-0.9/pypy/tool/build/bin/gentoo_init.d #!/sbin/runscript +#pypy-dev: unusual-interpreter ./usr/share/pypy-0.9/pypy/tool/build/bin/gentoo_init.d #!/sbin/runscript # This is the name of the interpreted interpreter. Renaming it to py makes no sense pypy-dev: script-with-language-extension usr/bin/py.py Modified: pypy/build/ubuntu/debian/pypy-lib.install ============================================================================== --- pypy/build/ubuntu/debian/pypy-lib.install (original) +++ pypy/build/ubuntu/debian/pypy-lib.install Tue Mar 2 16:33:58 2010 @@ -1,2 +1,2 @@ -lib-python usr/share/pypy-1.0 -pypy/lib usr/share/pypy-1.0/pypy +lib-python usr/share/pypy-1.2 +pypy/lib usr/share/pypy-1.2/pypy Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 2 16:33:58 2010 @@ -9,14 +9,14 @@ DEB_BUILD_ARCH := $(shell dpkg-architecture -qDEB_BUILD_ARCH) DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) -VERSION=1.0 +VERSION=1.2 get-orig-source: set -e ; \ - svn co http://codespeak.net/svn/pypy/dist pypy-svn ; \ + svn co http://codespeak.net/svn/pypy/trunk pypy-svn ; \ REVISION=`svnversion pypy-svn/` ; \ find pypy-svn/ -depth -type d -name ".svn" | xargs rm -rf ; \ - tar cfz pypy_1.0.0-svn$$REVISION.orig.tar.gz pypy-svn/ ; \ + tar cfz pypy_$(VERSION).0-svn$$REVISION.orig.tar.gz pypy-svn/ ; \ rm -rf pypy-svn/ Makefile: debian/Makefile.in From arigo at codespeak.net Tue Mar 2 16:35:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 16:35:21 +0100 (CET) Subject: [pypy-svn] r71645 - pypy/trunk/pypy/doc Message-ID: <20100302153521.68AF7282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 16:35:19 2010 New Revision: 71645 Modified: pypy/trunk/pypy/doc/getting-started-dev.txt Log: Update. Modified: pypy/trunk/pypy/doc/getting-started-dev.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started-dev.txt (original) +++ pypy/trunk/pypy/doc/getting-started-dev.txt Tue Mar 2 16:35:19 2010 @@ -334,7 +334,7 @@ ++++++++++++++++++++++++++++ `ctypes`_ is included in CPython 2.5 and higher. CPython 2.4 users needs to -install it (version 0.9.9.6 or later) if they want to run low-level tests. See +install it if they want to run low-level tests. See the `download page of ctypes`_. .. _`download page of ctypes`: http://sourceforge.net/project/showfiles.php?group_id=71702 From arigo at codespeak.net Tue Mar 2 16:55:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 16:55:26 +0100 (CET) Subject: [pypy-svn] r71646 - pypy/trunk/pypy/doc/jit Message-ID: <20100302155526.B4A0E282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 16:55:24 2010 New Revision: 71646 Modified: pypy/trunk/pypy/doc/jit/overview.txt Log: Update. Modified: pypy/trunk/pypy/doc/jit/overview.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/overview.txt (original) +++ pypy/trunk/pypy/doc/jit/overview.txt Tue Mar 2 16:55:24 2010 @@ -16,23 +16,30 @@ -------- Writing an interpreter for a complex dynamic language like Python is not -a small task. So doing it a high-level language looks like a good idea, -because high-level languages have many advantages over low-level ones -(flexibility, ease of implementation, no low-level issues...). This is -the basic observation behind PyPy. - -But coding in a high-level language has other benefits beyond the -obvious ones. Perhaps most importantly, it allows the language -interpreter to be analyzed when turned into a compiler. This is -precisely what our JIT compiler generator does. Based on tracing -JIT techniques, **it can turn the interpreter of an arbitrary -dynamic language into a just-in-time compiler for the same language.** -It works mostly automatically and only needs guidance by the language -implementor in the form of a small number of hints in the source code of -the interpreter. The resulting JIT compiler has the same language -semantics as the original interpreter by construction. It generates -machine code for the user program while aggressively optimizing it, -leading to a big performance boost. +a small task, especially if, for performance goals, we want to write a +Just-in-Time (JIT) compiler too. + +The good news is that it's not what we did. We indeed wrote an +interpreter for Python, but we never wrote any JIT compiler for Python +in PyPy. Instead, we use the fact that our interpreter for Python is +written in RPython, which is a nice, high-level language -- and we turn +it *automatically* into a JIT compiler for Python. + +This transformation is of course completely transparent to the user, +i.e. the programmer writing Python programs. The goal (which we +achieved) is to support *all* Python features -- including, for example, +random frame access and debuggers. But it is also mostly transparent to +the language implementor, i.e. to the source code of the Python +interpreter. It only needs a bit of guidance: we had to put a small +number of hints in the source code of our interpreter. Based on these +hints, the *JIT compiler generator* produces a JIT compiler which has +the same language semantics as the original interpreter by construction. +This JIT compiler itself generates machine code at runtime, aggressively +optimizing the user's program and leading to a big performance boost, +while keeping the semantics unmodified. Of course, the interesting bit +is that our Python language interpreter can evolve over time without +getting out of sync with the JIT compiler. + The path we followed -------------------- @@ -47,13 +54,15 @@ compilers. If this turns out to be correct, the practical speed of dynamic languages could be vastly improved. -Today (beginning 2009), our prototype is no longer using partial -evaluation -- at least not in a way that would convince paper reviewers. -It is instead based on the notion of *tracing JIT,* recently studied for -Java and JavaScript. When compared to all existing tracing JITs so far, -however, partial evaluation gives us some extra techniques that we -already had in our previous JIT generators, notably how to optimize -structures by removing allocations. +All these previous JIT compiler generators were producing JIT compilers +similar to the hand-written Psyco. But today, starting from 2009, our +prototype is no longer using partial evaluation -- at least not in a way +that would convince paper reviewers. It is instead based on the notion +of *tracing JIT,* recently studied for Java and JavaScript. When +compared to all existing tracing JITs so far, however, partial +evaluation gives us some extra techniques that we already had in our +previous JIT generators, notably how to optimize structures by removing +allocations. The closest comparison to our current JIT is Tamarin's TraceMonkey. However, this JIT compiler is written manually, which is quite some @@ -87,12 +96,8 @@ is modified, so that they cannot get out of sync no matter how fast the language evolves. -* Fast enough: we think that we can get some rather good performance out - of the generated JIT compilers. That's the whole point, of course. - Previous experience shows that it should be possible. Our previous - generated JIT compilers were similar to the hand-written Psyco; due - to limits in automating the way Psyco works, our current generated - JIT compilers are instead similar to tracing JITs like TraceMonkey. +* Fast enough: we can get some rather good performance out of the + generated JIT compilers. That's the whole point, of course. Alternative approaches to improve speed From arigo at codespeak.net Tue Mar 2 17:17:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 17:17:27 +0100 (CET) Subject: [pypy-svn] r71648 - pypy/extradoc/talk Message-ID: <20100302161727.2B4B0282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 17:17:25 2010 New Revision: 71648 Modified: pypy/extradoc/talk/bibtex.bib Log: Update. Modified: pypy/extradoc/talk/bibtex.bib ============================================================================== --- pypy/extradoc/talk/bibtex.bib (original) +++ pypy/extradoc/talk/bibtex.bib Tue Mar 2 17:17:25 2010 @@ -20,6 +20,14 @@ year = {2008} }, + at phdthesis{antocuni_phd_2010, + type = {Ph.D. Thesis}, + title = {High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages}, + school = {Universit\`a di Genova}, + author = {Antonio Cuni}, + year = {2010} +}, + @inproceedings{ancona_rpython:dls_2007, address = {Montreal, Quebec, Canada}, title = {{RPython:} A Step towards Reconciling Dynamically and Statically Typed {OO} Languages}, From arigo at codespeak.net Tue Mar 2 17:19:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 17:19:13 +0100 (CET) Subject: [pypy-svn] r71649 - pypy/trunk/pypy/doc Message-ID: <20100302161913.E8421282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 17:19:12 2010 New Revision: 71649 Modified: pypy/trunk/pypy/doc/index.txt Log: Update. Modified: pypy/trunk/pypy/doc/index.txt ============================================================================== --- pypy/trunk/pypy/doc/index.txt (original) +++ pypy/trunk/pypy/doc/index.txt Tue Mar 2 17:19:12 2010 @@ -8,7 +8,7 @@ Getting into PyPy ... ============================================= -* `Release 1.1`_: the latest official release +* `Release 1.2`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -56,4 +56,4 @@ .. _`Documentation`: docindex.html .. _`Getting Started`: getting-started.html .. _papers: extradoc.html -.. _`Release 1.1`: release-1.1.0.html +.. _`Release 1.2`: release-1.2.0.html From arigo at codespeak.net Tue Mar 2 17:19:23 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 17:19:23 +0100 (CET) Subject: [pypy-svn] r71650 - pypy/trunk/pypy/doc Message-ID: <20100302161923.7F875282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 17:19:21 2010 New Revision: 71650 Modified: pypy/trunk/pypy/doc/extradoc.txt Log: Add Antonio's thesis. Modified: pypy/trunk/pypy/doc/extradoc.txt ============================================================================== --- pypy/trunk/pypy/doc/extradoc.txt (original) +++ pypy/trunk/pypy/doc/extradoc.txt Tue Mar 2 17:19:21 2010 @@ -7,6 +7,9 @@ *Articles about PyPy published so far, most recent first:* (bibtex_ file) +* `High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages`_, + A. Cuni, Ph.D. thesis + * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo @@ -55,6 +58,7 @@ .. _bibtex: http://codespeak.net/svn/pypy/extradoc/talk/bibtex.bib +.. _`High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages`: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf .. _`How to *not* write Virtual Machines for Dynamic Languages`: http://codespeak.net/svn/pypy/extradoc/talk/dyla2007/dyla.pdf .. _`Tracing the Meta-Level: PyPy's Tracing JIT Compiler`: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit.pdf .. _`Faster than C#: Efficient Implementation of Dynamic Languages on .NET`: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009-dotnet/cli-jit.pdf From arigo at codespeak.net Tue Mar 2 17:22:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 17:22:59 +0100 (CET) Subject: [pypy-svn] r71651 - pypy/extradoc/talk Message-ID: <20100302162259.50E3A282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 17:22:57 2010 New Revision: 71651 Modified: pypy/extradoc/talk/bibtex.bib Log: Update, thanks antocuni. Modified: pypy/extradoc/talk/bibtex.bib ============================================================================== --- pypy/extradoc/talk/bibtex.bib (original) +++ pypy/extradoc/talk/bibtex.bib Tue Mar 2 17:22:57 2010 @@ -23,7 +23,7 @@ @phdthesis{antocuni_phd_2010, type = {Ph.D. Thesis}, title = {High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages}, - school = {Universit\`a di Genova}, + school = {{DISI}, Universit\'a di Genova}, author = {Antonio Cuni}, year = {2010} }, From arigo at codespeak.net Tue Mar 2 17:29:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 17:29:54 +0100 (CET) Subject: [pypy-svn] r71652 - pypy/trunk/pypy/doc Message-ID: <20100302162954.B5686282BD5@codespeak.net> Author: arigo Date: Tue Mar 2 17:29:52 2010 New Revision: 71652 Modified: pypy/trunk/pypy/doc/extradoc.txt Log: Mention RuPy 2009 and PyCon 2010. Modified: pypy/trunk/pypy/doc/extradoc.txt ============================================================================== --- pypy/trunk/pypy/doc/extradoc.txt (original) +++ pypy/trunk/pypy/doc/extradoc.txt Tue Mar 2 17:29:52 2010 @@ -76,9 +76,17 @@ Talks and Presentations ---------------------------------- +Talks in 2010 ++++++++++++++ + +* `PyCon 2010`_. + + Talks in 2009 +++++++++++++ +* `RuPy 2009`_. + * `EuroPython talks 2009`_. * `PyCon talks 2009`_. @@ -231,6 +239,8 @@ * `Architecture introduction slides`_ a mostly up-to-date introduction for the Amsterdam PyPy-Sprint Dec 2003. +.. _`PyCon 2010`: http://morepypy.blogspot.com/2010/02/pycon-2010-report.html +.. _`RuPy 2009`: http://morepypy.blogspot.com/2009/11/pypy-on-rupy-2009.html .. _`PyPy 3000`: http://codespeak.net/pypy/extradoc/talk/ep2006/pypy3000.txt .. _`What can PyPy do for you`: http://codespeak.net/pypy/extradoc/talk/ep2006/usecases-slides.html .. _`PyPy introduction at EuroPython 2006`: http://codespeak.net/pypy/extradoc/talk/ep2006/intro.pdf From getxsick at codespeak.net Tue Mar 2 17:46:12 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 17:46:12 +0100 (CET) Subject: [pypy-svn] r71653 - pypy/build/ubuntu/debian Message-ID: <20100302164612.130E7282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 17:46:10 2010 New Revision: 71653 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/changelog Log: fix translate options and broken revision Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 17:46:10 2010 @@ -1,7 +1,7 @@ TARGET=pypy/translator/goal/targetpypystandalone TRANSLATE=pypy/translator/goal/translate.py -TRANSLATEOPTS=--batch --source --Ojit +TRANSLATEOPTS=--batch --source -Ojit TARGETOPTS=%(TARGETOPTS)s PREFIX=%(PREFIX)s OUTPUTDIR=debian/tmp/usr/bin @@ -13,12 +13,12 @@ test: export TMPDIR = $(CURDIR)/tests-tmp test: - @rm -rf $(TMPDIR) - mkdir $(TMPDIR) - set -e; for SECTION in interpreter lib; do \ - time py/bin/py.test pypy/$$SECTION || true; \ - echo Finished tsting section $$SECTION; \ - done + @rm -rf $(TMPDIR) + mkdir $(TMPDIR) + set -e; for SECTION in interpreter lib; do \ + time py/bin/py.test pypy/$$SECTION || true; \ + echo Finished tsting section $$SECTION; \ + done .NOTPARALLEL: $(BINARIES) Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Tue Mar 2 17:46:10 2010 @@ -1,4 +1,4 @@ -pypy (1.2.0-svn71592-1) unstable; urgency=low +pypy (1.2.0-svn71646-1) unstable; urgency=low * New upstream release. * New maintainer. From getxsick at codespeak.net Tue Mar 2 18:12:31 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 18:12:31 +0100 (CET) Subject: [pypy-svn] r71655 - in pypy/build/ubuntu/debian: . source Message-ID: <20100302171231.AFB38282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 18:12:30 2010 New Revision: 71655 Added: pypy/build/ubuntu/debian/source/ pypy/build/ubuntu/debian/source/format Modified: pypy/build/ubuntu/debian/changelog Log: switch to dpkg-source 3.0 (native) format Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Tue Mar 2 18:12:30 2010 @@ -2,8 +2,9 @@ * New upstream release. * New maintainer. + * Switch to dpkg-source 3.0 (native) format - -- Bartosz Skowron Mon, 01 Mar 2010 18:30:44 +0100 + -- Bartosz Skowron Tue, 02 Mar 2010 18:08:37 +0100 pypy (1.0.0-svn55443-2) unstable; urgency=low Added: pypy/build/ubuntu/debian/source/format ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/source/format Tue Mar 2 18:12:30 2010 @@ -0,0 +1 @@ +3.0 (native) From arigo at codespeak.net Tue Mar 2 18:21:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 18:21:19 +0100 (CET) Subject: [pypy-svn] r71656 - pypy/trunk/pypy/doc Message-ID: <20100302172119.12E42282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 18:21:18 2010 New Revision: 71656 Modified: pypy/trunk/pypy/doc/docindex.txt pypy/trunk/pypy/doc/getting-started-python.txt pypy/trunk/pypy/doc/translation.txt Log: Update the version number. Modified: pypy/trunk/pypy/doc/docindex.txt ============================================================================== --- pypy/trunk/pypy/doc/docindex.txt (original) +++ pypy/trunk/pypy/doc/docindex.txt Tue Mar 2 18:21:18 2010 @@ -73,9 +73,9 @@ Windows, on top of .NET, and on top of Java. To dig into PyPy it is recommended to try out the current Subversion HEAD, which is always working or mostly working, -instead of the `release 1.1.0`__. +instead of the latest release, which is `1.2.0`__. -.. __: release-1.1.0.html +.. __: release-1.2.0.html PyPy is mainly developed on Linux and Mac OS X. Windows is supported, but platform-specific bugs tend to take longer before we notice and fix Modified: pypy/trunk/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started-python.txt (original) +++ pypy/trunk/pypy/doc/getting-started-python.txt Tue Mar 2 18:21:18 2010 @@ -213,11 +213,11 @@ ``PREFIX/pypy/lib`` can all be found. The prefixes that are tried are:: . - ./share/pypy-1.1 + ./share/pypy-1.2 .. - ../share/pypy-1.1 + ../share/pypy-1.2 ../.. - ../../share/pypy-1.1 + ../../share/pypy-1.2 ../../.. etc. Modified: pypy/trunk/pypy/doc/translation.txt ============================================================================== --- pypy/trunk/pypy/doc/translation.txt (original) +++ pypy/trunk/pypy/doc/translation.txt Tue Mar 2 18:21:18 2010 @@ -27,7 +27,7 @@ this task into several steps, and the purpose of this document is to introduce them. -As of the 1.1 release, RPython_ programs can be translated into the following +As of the 1.2 release, RPython_ programs can be translated into the following languages/platforms: C/POSIX, CLI/.NET and Java/JVM (in addition, there's `a backend`_ that translates `application-level`_ into `interpreter-level`_ code, but this is a special From fijal at codespeak.net Tue Mar 2 19:51:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 19:51:14 +0100 (CET) Subject: [pypy-svn] r71657 - pypy/build/bot2/pypybuildbot Message-ID: <20100302185114.F1FA0282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 19:51:13 2010 New Revision: 71657 Modified: pypy/build/bot2/pypybuildbot/master.py Log: indent Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Tue Mar 2 19:51:13 2010 @@ -107,7 +107,7 @@ 'schedulers': [ Nightly("nightly-first", [LINUX32], hour=4, minute=44), - Nightly("nightly", [APPLVLLINUX32, APPLVLWIN32, + Nightly("nightly", [APPLVLLINUX32, APPLVLWIN32, STACKLESSAPPLVLLINUX32, JITLINUX32, OJITLINUX32, MACOSX32], hour=4, minute=45), From fijal at codespeak.net Tue Mar 2 20:21:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 20:21:12 +0100 (CET) Subject: [pypy-svn] r71658 - pypy/trunk/pypy/doc Message-ID: <20100302192112.112B4282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 20:21:11 2010 New Revision: 71658 Modified: pypy/trunk/pypy/doc/contributor.txt Log: fix spelling to official one Modified: pypy/trunk/pypy/doc/contributor.txt ============================================================================== --- pypy/trunk/pypy/doc/contributor.txt (original) +++ pypy/trunk/pypy/doc/contributor.txt Tue Mar 2 20:21:11 2010 @@ -8,7 +8,7 @@ Armin Rigo - Maciek Fijalkowski + Maciej Fijalkowski Carl Friedrich Bolz Samuele Pedroni Antonio Cuni From arigo at codespeak.net Tue Mar 2 20:39:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Mar 2010 20:39:45 +0100 (CET) Subject: [pypy-svn] r71659 - pypy/trunk Message-ID: <20100302193945.AD95D282BD4@codespeak.net> Author: arigo Date: Tue Mar 2 20:39:44 2010 New Revision: 71659 Modified: pypy/trunk/LICENSE Log: Update fijal's name here too. Modified: pypy/trunk/LICENSE ============================================================================== --- pypy/trunk/LICENSE (original) +++ pypy/trunk/LICENSE Tue Mar 2 20:39:44 2010 @@ -35,7 +35,7 @@ copyrighted by one or more of the following people and organizations: Armin Rigo - Maciek Fijalkowski + Maciej Fijalkowski Carl Friedrich Bolz Samuele Pedroni Antonio Cuni From fijal at codespeak.net Tue Mar 2 20:43:45 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 20:43:45 +0100 (CET) Subject: [pypy-svn] r71660 - pypy/branch/jit-sandbox/pypy/translator/sandbox Message-ID: <20100302194345.9061E282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 20:43:43 2010 New Revision: 71660 Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/sandlib.py Log: We don't support python 2.3 anyway and that generates DeprecationWarning from pylib, use subprocess from stdlib Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/sandlib.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/sandbox/sandlib.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/sandbox/sandlib.py Tue Mar 2 20:43:43 2010 @@ -10,7 +10,7 @@ from pypy.rpython.module.ll_os_stat import s_StatResult from pypy.tool.ansi_print import AnsiLog from pypy.rlib.rarithmetic import r_longlong -from py.compat import subprocess +import subprocess from pypy.tool.killsubprocess import killsubprocess class MyAnsiLog(AnsiLog): From getxsick at codespeak.net Tue Mar 2 21:05:15 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 21:05:15 +0100 (CET) Subject: [pypy-svn] r71661 - pypy/build/ubuntu/debian Message-ID: <20100302200515.35439282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 21:04:58 2010 New Revision: 71661 Modified: pypy/build/ubuntu/debian/Makefile.in Log: fix path to session dirs Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 21:04:58 2010 @@ -27,8 +27,8 @@ @rm -rf $(TMPDIR) mkdir $(TMPDIR) $(TRANSLATE) $(TRANSLATEOPTS) $(TARGET) $(TARGETOPTS) - make -C $(TMPDIR)/debian-pypy-usession-0/testing_1 - install -D $(TMPDIR)/debian-pypy-usession-0/testing_1/testing_1 $@ + make -C $(TMPDIR)/usession-0/testing_1 + install -D $(TMPDIR)/usession-0/testing_1/testing_1 $@ clean: rm -rf bin From getxsick at codespeak.net Tue Mar 2 21:10:08 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 21:10:08 +0100 (CET) Subject: [pypy-svn] r71664 - pypy/build/ubuntu/debian Message-ID: <20100302201008.96A3E282BD5@codespeak.net> Author: getxsick Date: Tue Mar 2 21:09:37 2010 New Revision: 71664 Modified: pypy/build/ubuntu/debian/configure.py Log: remove target options for i386, use default instead. it was commented out anyway Modified: pypy/build/ubuntu/debian/configure.py ============================================================================== --- pypy/build/ubuntu/debian/configure.py (original) +++ pypy/build/ubuntu/debian/configure.py Tue Mar 2 21:09:37 2010 @@ -29,7 +29,6 @@ 'BINARIES': 'bin/pypy', } options = {} - #options['i386'] = {'TARGETOPTS': '--allworkingmodules -Ojit'} substitutions = dict(PREFIX=prefix, **default) substitutions.update(options.get(build_arch, {})) From fijal at codespeak.net Tue Mar 2 21:12:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 21:12:52 +0100 (CET) Subject: [pypy-svn] r71666 - pypy/branch/jit-sandbox/pypy/translator/sandbox/test Message-ID: <20100302201252.1ED5A282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 21:12:47 2010 New Revision: 71666 Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Log: A failing test (finally!) Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Tue Mar 2 21:12:47 2010 @@ -1,6 +1,7 @@ import py import sys, os, time import struct +import subprocess from pypy.rpython.lltypesystem import rffi from pypy.translator.interactive import Translation @@ -19,8 +20,8 @@ write_message(g, result, resulttype) g.flush() -def compile(f): - t = Translation(f, backend='c', standalone=True, sandbox=True, gc='ref') +def compile(f, gc='ref'): + t = Translation(f, backend='c', standalone=True, sandbox=True, gc=gc) return str(t.compile()) @@ -131,6 +132,24 @@ f.close() assert tail == "" +def test_hybrid_gc(): + def entry_point(argv): + return int(len("x" * int(argv[0])) < 350) + + exe = compile(entry_point, gc='hybrid') + pipe = subprocess.Popen([exe, '1000000'], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GENERATIONGC_NURSERY",), None) + expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420), OSError(5232, "xyz")) + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + class TestPrintedResults: def run(self, entry_point, args, expected): From fijal at codespeak.net Tue Mar 2 21:58:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 21:58:33 +0100 (CET) Subject: [pypy-svn] r71668 - pypy/branch/jit-sandbox/pypy/translator/sandbox/test Message-ID: <20100302205833.96C8C282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 21:58:32 2010 New Revision: 71668 Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Log: Apparently this test should pass. malloc_varsize_marknsweep is called and returns non-zero Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Tue Mar 2 21:58:32 2010 @@ -134,10 +134,13 @@ def test_hybrid_gc(): def entry_point(argv): - return int(len("x" * int(argv[0])) < 350) + l = [] + for i in range(int(argv[1])): + l.append("x" * int(argv[2])) + return int(len(l) > 1000) exe = compile(entry_point, gc='hybrid') - pipe = subprocess.Popen([exe, '1000000'], stdout=subprocess.PIPE, + pipe = subprocess.Popen([exe, '10', '10000'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) g = pipe.stdin f = pipe.stdout From getxsick at codespeak.net Tue Mar 2 22:30:30 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 22:30:30 +0100 (CET) Subject: [pypy-svn] r71669 - in pypy/build/ubuntu/debian: . scripts Message-ID: <20100302213030.7F6E7282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 22:30:28 2010 New Revision: 71669 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/pypy-lib.links pypy/build/ubuntu/debian/rules pypy/build/ubuntu/debian/scripts/jscompile pypy/build/ubuntu/debian/scripts/py.py pypy/build/ubuntu/debian/scripts/pypy-translate Log: update build to 1.2 release Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 22:30:28 2010 @@ -35,8 +35,8 @@ rm -rf build-* rm -rf tests-tmp rm -rf pypy/_cache - rm -rf py/c-extension/greenlet/build - rm -f py/c-extension/greenlet/greenlet.so + rm -rf greenlet/build + rm -f greenlet/_greenlet.so find . -name "*.pyc" | xargs rm -f install: all Modified: pypy/build/ubuntu/debian/pypy-lib.links ============================================================================== --- pypy/build/ubuntu/debian/pypy-lib.links (original) +++ pypy/build/ubuntu/debian/pypy-lib.links Tue Mar 2 22:30:28 2010 @@ -1 +1 @@ -usr/share/pypy-1.0/pypy/lib usr/share/pypy-1.0/lib +usr/share/pypy-1.2/pypy/lib usr/share/pypy-1.2/lib Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 2 22:30:28 2010 @@ -62,11 +62,11 @@ chmod a+x $$f ; \ fi ; \ done - chmod a+x debian/pypy-lib/usr/share/pypy-*/lib-python/2.4.1/plat-*/regen - for f in debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.4.1/test/test_largefile.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.4.1/test/test_largefile.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.4.1/cgi.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.4.1/bsddb/dbshelve.py \ + chmod a+x debian/pypy-lib/usr/share/pypy-*/lib-python/2.5.2/plat-*/regen + for f in debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/test/test_largefile.py \ + debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/test/test_largefile.py \ + debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/cgi.py \ + debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/bsddb/dbshelve.py \ debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/pybench.py \ debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/Setup.py \ debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/Setup.py \ Modified: pypy/build/ubuntu/debian/scripts/jscompile ============================================================================== --- pypy/build/ubuntu/debian/scripts/jscompile (original) +++ pypy/build/ubuntu/debian/scripts/jscompile Tue Mar 2 22:30:28 2010 @@ -1,7 +1,7 @@ #!/usr/bin/python import sys -sys.path.append('/usr/share/pypy-1.0') -sys.path.append('/usr/share/pypy-1.0/pypy/bin') +sys.path.append('/usr/share/pypy-1.2') +sys.path.append('/usr/share/pypy-1.2/pypy/bin') sys.path.remove('/usr/bin') -execfile('/usr/share/pypy-1.0/pypy/bin/jscompile.py') +execfile('/usr/share/pypy-1.2/pypy/bin/jscompile.py') Modified: pypy/build/ubuntu/debian/scripts/py.py ============================================================================== --- pypy/build/ubuntu/debian/scripts/py.py (original) +++ pypy/build/ubuntu/debian/scripts/py.py Tue Mar 2 22:30:28 2010 @@ -1,5 +1,5 @@ #!/usr/bin/python import sys -sys.path.insert(0, '/usr/share/pypy-1.0') +sys.path.insert(0, '/usr/share/pypy-1.2') sys.path.remove('/usr/bin') -execfile('/usr/share/pypy-1.0/pypy/bin/py.py') +execfile('/usr/share/pypy-1.2/pypy/bin/py.py') Modified: pypy/build/ubuntu/debian/scripts/pypy-translate ============================================================================== --- pypy/build/ubuntu/debian/scripts/pypy-translate (original) +++ pypy/build/ubuntu/debian/scripts/pypy-translate Tue Mar 2 22:30:28 2010 @@ -1,3 +1,3 @@ #!/bin/sh -/usr/share/pypy-1.0/pypy/translator/goal/translate.py "$@" +/usr/share/pypy-1.2/pypy/translator/goal/translate.py "$@" From fijal at codespeak.net Tue Mar 2 23:10:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 2 Mar 2010 23:10:40 +0100 (CET) Subject: [pypy-svn] r71675 - pypy/build/testrunner Message-ID: <20100302221040.D0B5C282BD4@codespeak.net> Author: fijal Date: Tue Mar 2 23:10:39 2010 New Revision: 71675 Modified: pypy/build/testrunner/runner.py Log: Kill some more 2.3 reminescense (and 2.2 apparently) Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Tue Mar 2 23:10:39 2010 @@ -1,6 +1,6 @@ import sys, os, signal, thread, Queue, time import py -from py.compat import subprocess, optparse +import subprocess, optparse if sys.platform == 'win32': PROCESS_TERMINATE = 0x1 From getxsick at codespeak.net Tue Mar 2 23:51:29 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 2 Mar 2010 23:51:29 +0100 (CET) Subject: [pypy-svn] r71678 - pypy/build/ubuntu/debian Message-ID: <20100302225129.10FF3282BD4@codespeak.net> Author: getxsick Date: Tue Mar 2 23:51:28 2010 New Revision: 71678 Modified: pypy/build/ubuntu/debian/Makefile.in Log: run tests (app, lib-python and JIT) after trasnalation Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 2 23:51:28 2010 @@ -12,13 +12,27 @@ all: $(BINARIES) test test: export TMPDIR = $(CURDIR)/tests-tmp +test: export PYTHONPATH = ".:"$(PYTHONPATH) test: @rm -rf $(TMPDIR) mkdir $(TMPDIR) - set -e; for SECTION in interpreter lib; do \ - time py/bin/py.test pypy/$$SECTION || true; \ - echo Finished tsting section $$SECTION; \ - done + cp build-default/usession-$$USER/testing_1/testing_1 pypy/translator/goal/pypy-c + set -e; python testrunner/runner.py \ + --logfile=pytest-A.log \ + --config=pypy/pytest-A.cfg \ + --root=pypy \ + --timeout=1800 || true;\ + echo "Finished testing app-level (-A)"; \ + python pypy/test_all.py \ + --pypy=pypy/translator/goal/pypy-c \ + --resultlog=cpython.log \ + lib-python || true; \ + echo "Finished testing lib-python"; \ + python pypy/test_all.py \ + --pypy=pypy/translator/goal/pypy-c \ + --resultlog=pypyjit.log \ + pypy/module/pypyjit/test || true; \ + echo "Finished testing JIT"; .NOTPARALLEL: $(BINARIES) From fijal at codespeak.net Wed Mar 3 00:11:57 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 00:11:57 +0100 (CET) Subject: [pypy-svn] r71679 - in pypy/branch/jit-sandbox/pypy: rlib translator/sandbox/test Message-ID: <20100302231157.EA42F282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 00:11:56 2010 New Revision: 71679 Modified: pypy/branch/jit-sandbox/pypy/rlib/rmmap.py pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Log: Be extra paranoid on rmmap. This is non-issue, since this stuff is unsupported by sandbox anyway, however if one day we start supporting it, there is a test. Modified: pypy/branch/jit-sandbox/pypy/rlib/rmmap.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/rlib/rmmap.py (original) +++ pypy/branch/jit-sandbox/pypy/rlib/rmmap.py Wed Mar 3 00:11:56 2010 @@ -91,27 +91,32 @@ _ACCESS_DEFAULT, ACCESS_READ, ACCESS_WRITE, ACCESS_COPY = range(4) def external(name, args, result): - return rffi.llexternal(name, args, result, + unsafe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_) + safe = rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, - sandboxsafe=True, threadsafe=True) + sandboxsafe=True, threadsafe=False) + return unsafe, safe def winexternal(name, args, result): - return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win', sandboxsafe=True, threadsafe=True) + return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win') PTR = rffi.CCHARP -c_memmove = external('memmove', [PTR, PTR, size_t], lltype.Void) +c_memmove, _ = external('memmove', [PTR, PTR, size_t], lltype.Void) if _POSIX: has_mremap = cConfig['has_mremap'] - c_mmap = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, + c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, rffi.INT, off_t], PTR) - c_munmap = external('munmap', [PTR, size_t], rffi.INT) - c_msync = external('msync', [PTR, size_t, rffi.INT], rffi.INT) + c_munmap, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT) + c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT) if has_mremap: - c_mremap = external('mremap', [PTR, size_t, size_t, rffi.ULONG], PTR) + c_mremap, _ = external('mremap', + [PTR, size_t, size_t, rffi.ULONG], PTR) - _get_page_size = external('getpagesize', [], rffi.INT) + # this one is always safe + _, _get_page_size = external('getpagesize', [], rffi.INT) def _get_error_no(): return rposix.get_errno() @@ -634,14 +639,14 @@ flags = MAP_PRIVATE | MAP_ANONYMOUS prot = PROT_EXEC | PROT_READ | PROT_WRITE hintp = rffi.cast(PTR, hint.pos) - res = c_mmap(hintp, map_size, prot, flags, -1, 0) + res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0) if res == rffi.cast(PTR, -1): raise MemoryError hint.pos += map_size return res alloc._annenforceargs_ = (int,) - free = c_munmap + free = c_munmap_safe elif _MS_WINDOWS: def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT): Modified: pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py (original) +++ pypy/branch/jit-sandbox/pypy/translator/sandbox/test/test_sandbox.py Wed Mar 3 00:11:56 2010 @@ -153,6 +153,51 @@ rescode = pipe.wait() assert rescode == 0 +def test_safe_alloc(): + from pypy.rlib.rmmap import alloc, free + + def entry_point(argv): + one = alloc(1024) + free(one, 1024) + return 0 + + exe = compile(entry_point) + pipe = subprocess.Popen([exe], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + +def test_unsafe_mmap(): + py.test.skip("Since this stuff is unimplemented, it won't work anyway " + "however, the day it starts working, it should pass test") + from pypy.rlib.rmmap import mmap + + def entry_point(argv): + try: + res = mmap(0, 1024) + except OSError: + return 0 + return 1 + + exe = compile(entry_point) + pipe = subprocess.Popen([exe], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + expect(f, g, "mmap", ARGS, OSError(1, "xyz")) + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + class TestPrintedResults: def run(self, entry_point, args, expected): From fijal at codespeak.net Wed Mar 3 01:21:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 01:21:30 +0100 (CET) Subject: [pypy-svn] r71681 - in pypy/trunk/pypy/module/pypyjit: . test Message-ID: <20100303002130.5D068282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 01:21:28 2010 New Revision: 71681 Modified: pypy/trunk/pypy/module/pypyjit/policy.py pypy/trunk/pypy/module/pypyjit/test/test_policy.py Log: Look into functional. Most of these functions are not looked at since they contain loops, but a couple like X_Range.descr_next are Modified: pypy/trunk/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/policy.py Wed Mar 3 01:21:28 2010 @@ -5,7 +5,8 @@ def look_inside_pypy_module(self, modname): if (modname == '__builtin__.operation' or modname == '__builtin__.abstractinst' or - modname == '__builtin__.interp_classobj'): + modname == '__builtin__.interp_classobj' or + modname == '__builtin__.functional'): return True if '.' in modname: Modified: pypy/trunk/pypy/module/pypyjit/test/test_policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_policy.py Wed Mar 3 01:21:28 2010 @@ -30,6 +30,7 @@ assert not pypypolicy.look_inside_pypy_module('posix.interp_expat') assert pypypolicy.look_inside_pypy_module('__builtin__.operation') assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst') + assert pypypolicy.look_inside_pypy_module('__builtin__.functional') assert pypypolicy.look_inside_pypy_module('exceptions.interp_exceptions') for modname in 'pypyjit', 'signal', 'micronumpy', 'math': assert pypypolicy.look_inside_pypy_module(modname) From fijal at codespeak.net Wed Mar 3 01:54:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 01:54:18 +0100 (CET) Subject: [pypy-svn] r71682 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100303005418.A26F8282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 01:54:17 2010 New Revision: 71682 Modified: pypy/trunk/pypy/jit/metainterp/executor.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/test/test_basic.py Log: implement uint_floordiv Modified: pypy/trunk/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/executor.py Wed Mar 3 01:54:17 2010 @@ -31,6 +31,11 @@ z = llop.int_floordiv(lltype.Signed, box1.getint(), box2.getint()) return ConstInt(z) +def do_uint_floordiv(cpu, box1, box2): + z = llop.uint_floordiv(lltype.Unsigned, r_uint(box1.getint()), + r_uint(box2.getint())) + return ConstInt(intmask(z)) + def do_int_mod(cpu, box1, box2): z = llop.int_mod(lltype.Signed, box1.getint(), box2.getint()) return ConstInt(z) Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Wed Mar 3 01:54:17 2010 @@ -206,6 +206,7 @@ 'int_and', 'int_or', 'int_xor', 'int_rshift', 'int_lshift', 'uint_rshift', 'uint_lt', 'uint_le', 'uint_gt', 'uint_ge', + 'uint_floordiv', 'float_add', 'float_sub', 'float_mul', 'float_truediv', 'float_lt', 'float_le', 'float_eq', 'float_ne', 'float_gt', 'float_ge', Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Wed Mar 3 01:54:17 2010 @@ -142,6 +142,7 @@ 'INT_SUB/2', 'INT_MUL/2', 'INT_FLOORDIV/2', + 'UINT_FLOORDIV/2', 'INT_MOD/2', 'INT_AND/2', 'INT_OR/2', Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Wed Mar 3 01:54:17 2010 @@ -200,6 +200,15 @@ res = self.interp_operations(f, [42]) assert res == 42 + def test_uint_floordiv(self): + from pypy.rlib.rarithmetic import r_uint + + def f(a, b): + return a/b + + res = self.interp_operations(f, [r_uint(4), r_uint(3)]) + assert res == 1 + def test_direct_call(self): def g(n): return n + 2 From fijal at codespeak.net Wed Mar 3 02:07:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 02:07:05 +0100 (CET) Subject: [pypy-svn] r71683 - in pypy/trunk/pypy/jit: backend/x86 metainterp/test Message-ID: <20100303010705.0E5D6282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 02:07:04 2010 New Revision: 71683 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py pypy/trunk/pypy/jit/metainterp/test/test_executor.py Log: implement uint_floordiv Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Wed Mar 3 02:07:04 2010 @@ -718,6 +718,11 @@ genop_int_floordiv = genop_int_mod + def genop_uint_floordiv(self, op, arglocs, resloc): + self.mc.MOV(edx, eax) + self.mc.SAR(edx, imm(31)) + self.mc.IDIV(ecx) + def genop_new_with_vtable(self, op, arglocs, result_loc): assert result_loc is eax loc_vtable = arglocs[-1] Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Wed Mar 3 02:07:04 2010 @@ -510,6 +510,7 @@ def consider_int_floordiv(self, op): self._consider_int_div_or_mod(op, eax, edx) self.Perform(op, [eax, ecx], eax) + consider_uint_floordiv = consider_int_mod def _consider_compop(self, op, guard_op): vx = op.args[0] Modified: pypy/trunk/pypy/jit/metainterp/test/test_executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_executor.py Wed Mar 3 02:07:04 2010 @@ -130,7 +130,9 @@ (3, 3, 0)]), (rop.UINT_RSHIFT, [(-1, 4, intmask(r_uint(-1) >> r_uint(4))), ( 1, 4, intmask(r_uint(1) >> r_uint(4))), - ( 3, 3, 0)]) + ( 3, 3, 0)]), + (rop.UINT_FLOORDIV, [(4, 3, intmask(r_uint(4) / r_uint(3))), + (1, -1, intmask(r_uint(1) / r_uint(-1)))]) ]: for x, y, z in testcases: yield opnum, [x, y], z From fijal at codespeak.net Wed Mar 3 02:19:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 02:19:04 +0100 (CET) Subject: [pypy-svn] r71684 - pypy/extradoc/planning Message-ID: <20100303011904.6C7A4282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 02:19:02 2010 New Revision: 71684 Modified: pypy/extradoc/planning/jit.txt Log: a huge update Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Wed Mar 3 02:19:02 2010 @@ -11,43 +11,48 @@ - think out looking into functions or not, based on arguments, for example contains__Tuple should be unrolled if tuple is of constant - length + length. HARD, blocked by the fact that we don't know constants soon enough - look at example of storing small strings in large lists (any sane templating engine would do it) and not spend all the time in - _trace_and_drag_out_of_nursery + _trace_and_drag_out_of_nursery. + Requires thinking about card-marking GC, which is hard, postpone - improve tracing/blackholing speed (?) + Essential, especially blackholing in translate.py, as well as html5lib. - some guards will always fail if they ever start failing (e.g. the class version tag). Do something more clever about it. + DONE? Python interpreter: -- goal: on average <=5 guards per original bytecode +- goal: on average <=5 guards per original bytecode. + Almost achieved :-) pypy/jit/tool/otherviewer.py can view where we're + failing (red boxes out of jit-log-opt logging) - put the class into the structure to get only one promote when using an instance -- look why module.x does two calls to _lookup_where +- look why module.x does two calls to _lookup_where FIXED? - this example: http://paste.pocoo.org/show/181319/ showcases a problem that works fine as long as you not present a combination of oldstyle and newstyle classes. If you however present a combination of old and newstyle classes (try modifying) things go far slower and traces look bad. + DON'T DO THAT? Benchmark Notes ---------------------------- - spitfire: - - spends most of its time in subclass-of-list.append - - does completely horrible hackish things that happen to be fast on CPython - (i.e. calling locals() all the time) - - see http://paste.pocoo.org/show/169366/ for the python code that spitfire - produces for the template used in the benchmark + - it's an issue with GC, that's probably won't fix. On spitfire's small + benchmarks we're either matching CPython or are faster (if using cStringIO) - html5lib: + - we're faster (a bit) than CPython on a long enough run. blackholing is + an issue there. - slowness seems to be mostly the fault of PyUnicode_DecodeCharmap in module/_codecs/app_codecs.py. Are such things not jitted? - the tokenizer uses regular expressions and generators, which probably @@ -55,11 +60,12 @@ - spambayes - uses regular expressions and generators a lot + - regexes are 80% of runtime of long-enough run - ai - the slowness is the fault of generators and generator expressions - many of the generator expressions are a bit stupid (like tuple()) - + WON'T FIX, maybe? JIT-related Release Tasks @@ -70,10 +76,8 @@ scope of this section) wishlist: -- improve on predictability: don't trace into signals ... but produce just a - conditional call (or just abort the trace) - the checks that look whether profiling/tracing in the Python interpreter is - enabled look expensive. Do we want to do something about them? + enabled look expensive. Do we want to do something about them? DONE? @@ -81,9 +85,9 @@ META ----- -- stability! +- stability! DONE? -- keep test coverage in check +- keep test coverage in check DONE? - prevent too much method and fields demoting in the jit @@ -98,19 +102,11 @@ explosion - tracing aggressively will put pressure on the speed of tracing - what should we do about recursive calls? -- connecting compiled loops accross a call? things we know are missing --------------------------- -backend: -- speed of backend? - -Python interpreter: -- lookups of various kinds -- calls - tests: - find a test for r64742 (JitException capture) @@ -118,6 +114,7 @@ ----------------- Goal: be somehow faster than CPython in real programs + actually, DONE! Benchmarks: they live at svn+ssh://codespeak.net/svn/pypy/benchmarks @@ -133,15 +130,4 @@ memory usage ------------ -- we use too much memory during jitting. Notably of the following - types (in decreasing order of total size, for Pystone): - XXX is this still relevant? - - rpy_string - - GcArray of AbstractValue (unknown if fixedsize or not) - - DoneWithThisFrameRef - - dict {AbstractValue: SHORT} - - GcArray of ResOperation - - resizable list of AbstractValue - - ResOperation - - ResumeGuardDescr - - ConstInt +part here was out of date a lot. From fijal at codespeak.net Wed Mar 3 03:27:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:27:16 +0100 (CET) Subject: [pypy-svn] r71685 - pypy/trunk/pypy/module/_sre Message-ID: <20100303022716.E5B23282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:27:12 2010 New Revision: 71685 Modified: pypy/trunk/pypy/module/_sre/interp_sre.py Log: Avoid warning during annotation Modified: pypy/trunk/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/trunk/pypy/module/_sre/interp_sre.py (original) +++ pypy/trunk/pypy/module/_sre/interp_sre.py Wed Mar 3 03:27:12 2010 @@ -91,6 +91,11 @@ def w_reset(self): self.reset() + def create_regs(self, group_count): + """ Purely abstract method + """ + raise NotImplementedError + def w_create_regs(self, group_count): """Creates a tuple of index pairs representing matched groups, a format that's convenient for SRE_Match.""" From fijal at codespeak.net Wed Mar 3 03:30:50 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:30:50 +0100 (CET) Subject: [pypy-svn] r71686 - pypy/trunk/pypy/module/thread Message-ID: <20100303023050.91701282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:30:48 2010 New Revision: 71686 Modified: pypy/trunk/pypy/module/thread/os_thread.py Log: Avoid warnings during rtyping Modified: pypy/trunk/pypy/module/thread/os_thread.py ============================================================================== --- pypy/trunk/pypy/module/thread/os_thread.py (original) +++ pypy/trunk/pypy/module/thread/os_thread.py Wed Mar 3 03:30:48 2010 @@ -62,6 +62,8 @@ # The following lock is held whenever the fields # 'bootstrapper.w_callable' and 'bootstrapper.args' are in use. lock = None + args = None + w_callable = None def setup(space): if bootstrapper.lock is None: From fijal at codespeak.net Wed Mar 3 03:36:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:36:36 +0100 (CET) Subject: [pypy-svn] r71687 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100303023636.044ED282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:36:34 2010 New Revision: 71687 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py Log: Silence warning Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Wed Mar 3 03:36:34 2010 @@ -819,6 +819,7 @@ value = self.getvalue(op.args[0]) if value.is_virtual(): # optimizefindnode should ensure that fieldvalue is found + assert isinstance(value, VirtualValue) fieldvalue = value.getfield(op.descr, None) assert fieldvalue is not None self.make_equal_to(op.result, fieldvalue) From fijal at codespeak.net Wed Mar 3 03:38:01 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:38:01 +0100 (CET) Subject: [pypy-svn] r71688 - pypy/trunk/pypy/jit/backend/llgraph Message-ID: <20100303023801.88DE1282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:37:56 2010 New Revision: 71688 Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py Log: fix test Modified: pypy/trunk/pypy/jit/backend/llgraph/llimpl.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/llimpl.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/llimpl.py Wed Mar 3 03:37:56 2010 @@ -90,6 +90,7 @@ 'uint_ge' : (('int', 'int'), 'bool'), 'uint_xor' : (('int', 'int'), 'int'), 'uint_rshift' : (('int', 'int'), 'int'), + 'uint_floordiv' : (('int', 'int'), 'int'), 'float_add' : (('float', 'float'), 'float'), 'float_sub' : (('float', 'float'), 'float'), 'float_mul' : (('float', 'float'), 'float'), From fijal at codespeak.net Wed Mar 3 03:39:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:39:21 +0100 (CET) Subject: [pypy-svn] r71689 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100303023921.D312C282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:39:19 2010 New Revision: 71689 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py Log: Improve assert Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Wed Mar 3 03:39:19 2010 @@ -819,7 +819,7 @@ value = self.getvalue(op.args[0]) if value.is_virtual(): # optimizefindnode should ensure that fieldvalue is found - assert isinstance(value, VirtualValue) + assert isinstance(value, AbstractVirtualValue) fieldvalue = value.getfield(op.descr, None) assert fieldvalue is not None self.make_equal_to(op.result, fieldvalue) From fijal at codespeak.net Wed Mar 3 03:41:38 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:41:38 +0100 (CET) Subject: [pypy-svn] r71690 - in pypy/trunk/pypy/jit: backend backend/llgraph backend/llsupport metainterp Message-ID: <20100303024138.839B1282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:41:36 2010 New Revision: 71690 Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py Log: Store a base class of calldescr on CPU, hence avoiding demoting method get_extra_info up to abstract descr Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/runner.py Wed Mar 3 03:41:36 2010 @@ -74,6 +74,8 @@ class BaseCPU(model.AbstractCPU): supports_floats = True + CallDescrClass = Descr + def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, annmixlevel=None, gcdescr=None): Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Wed Mar 3 03:41:36 2010 @@ -17,6 +17,8 @@ class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts + CallDescrClass = BaseCallDescr + def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): assert type(opts) is not bool Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Wed Mar 3 03:41:36 2010 @@ -8,6 +8,8 @@ portal_calldescr = None done_with_this_frame_int_v = -1 + CallDescrClass = None # a base class for all CallDescrs + def __init__(self): self.fail_descr_list = [] Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Wed Mar 3 03:41:36 2010 @@ -1066,6 +1066,7 @@ return self.metainterp.assert_no_exception() def do_residual_call(self, argboxes, descr, exc): + assert isinstance(descr, self.metainterp.cpu.CallDescrClass) effectinfo = descr.get_extra_info() if effectinfo is None or effectinfo.forces_virtual_or_virtualizable: # residual calls require attention to keep virtualizables in-sync From fijal at codespeak.net Wed Mar 3 03:50:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:50:30 +0100 (CET) Subject: [pypy-svn] r71691 - pypy/branch/cleanup-warnings Message-ID: <20100303025030.7F5B7282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:50:28 2010 New Revision: 71691 Added: pypy/branch/cleanup-warnings/ - copied from r71690, pypy/trunk/ Log: A branch to clean up warnings From fijal at codespeak.net Wed Mar 3 03:51:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:51:09 +0100 (CET) Subject: [pypy-svn] r71692 - pypy/branch/asm-profile Message-ID: <20100303025109.D0C80282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:51:04 2010 New Revision: 71692 Removed: pypy/branch/asm-profile/ Log: This branch went nowhere so far From fijal at codespeak.net Wed Mar 3 03:53:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 03:53:46 +0100 (CET) Subject: [pypy-svn] r71693 - in pypy/trunk/pypy/jit/backend: . llgraph llsupport Message-ID: <20100303025346.DD6F9282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 03:53:44 2010 New Revision: 71693 Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/model.py Log: Revert 71690, will work on branch for that (it did not work that simple way) Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/runner.py Wed Mar 3 03:53:44 2010 @@ -74,8 +74,6 @@ class BaseCPU(model.AbstractCPU): supports_floats = True - CallDescrClass = Descr - def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, annmixlevel=None, gcdescr=None): Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Wed Mar 3 03:53:44 2010 @@ -17,8 +17,6 @@ class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts - CallDescrClass = BaseCallDescr - def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): assert type(opts) is not bool Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Wed Mar 3 03:53:44 2010 @@ -8,8 +8,6 @@ portal_calldescr = None done_with_this_frame_int_v = -1 - CallDescrClass = None # a base class for all CallDescrs - def __init__(self): self.fail_descr_list = [] From fijal at codespeak.net Wed Mar 3 04:19:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 04:19:11 +0100 (CET) Subject: [pypy-svn] r71694 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100303031911.10489282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 04:19:07 2010 New Revision: 71694 Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py Log: This belongs to previous commit Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Wed Mar 3 04:19:07 2010 @@ -1066,7 +1066,6 @@ return self.metainterp.assert_no_exception() def do_residual_call(self, argboxes, descr, exc): - assert isinstance(descr, self.metainterp.cpu.CallDescrClass) effectinfo = descr.get_extra_info() if effectinfo is None or effectinfo.forces_virtual_or_virtualizable: # residual calls require attention to keep virtualizables in-sync From fijal at codespeak.net Wed Mar 3 04:19:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 04:19:44 +0100 (CET) Subject: [pypy-svn] r71695 - in pypy/trunk/pypy/jit: backend/x86 metainterp/test Message-ID: <20100303031944.76F2D282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 04:19:42 2010 New Revision: 71695 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py pypy/trunk/pypy/jit/metainterp/test/test_executor.py Log: Clearly I should read intel manuals better. Improve tests, fix uint_floordiv Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Wed Mar 3 04:19:42 2010 @@ -719,9 +719,8 @@ genop_int_floordiv = genop_int_mod def genop_uint_floordiv(self, op, arglocs, resloc): - self.mc.MOV(edx, eax) - self.mc.SAR(edx, imm(31)) - self.mc.IDIV(ecx) + self.mc.XOR(edx, edx) + self.mc.DIV(ecx) def genop_new_with_vtable(self, op, arglocs, result_loc): assert result_loc is eax Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Wed Mar 3 04:19:42 2010 @@ -510,7 +510,8 @@ def consider_int_floordiv(self, op): self._consider_int_div_or_mod(op, eax, edx) self.Perform(op, [eax, ecx], eax) - consider_uint_floordiv = consider_int_mod + + consider_uint_floordiv = consider_int_floordiv def _consider_compop(self, op, guard_op): vx = op.args[0] Modified: pypy/trunk/pypy/jit/metainterp/test/test_executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_executor.py Wed Mar 3 04:19:42 2010 @@ -132,7 +132,14 @@ ( 1, 4, intmask(r_uint(1) >> r_uint(4))), ( 3, 3, 0)]), (rop.UINT_FLOORDIV, [(4, 3, intmask(r_uint(4) / r_uint(3))), - (1, -1, intmask(r_uint(1) / r_uint(-1)))]) + (1, -1, intmask(r_uint(1) / r_uint(-1))), + (110, 3, 36), + (-110, 3, intmask(r_uint(-110) / r_uint(3))), + (110, -3, intmask(r_uint(110) / r_uint(-3))), + (-110, -3, intmask(r_uint(-110) / r_uint(-3))), + (-110, -1, intmask(r_uint(-110) / r_uint(-1))), + (minint, 1, intmask(r_uint(minint) / r_uint(1))), + (-87, -87, intmask(r_uint(-87) / r_uint(-87)))]) ]: for x, y, z in testcases: yield opnum, [x, y], z From fijal at codespeak.net Wed Mar 3 04:22:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 04:22:04 +0100 (CET) Subject: [pypy-svn] r71696 - in pypy/branch/cleanup-warnings/pypy/jit: backend backend/llsupport backend/test metainterp Message-ID: <20100303032204.C8C43282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 04:22:03 2010 New Revision: 71696 Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py pypy/branch/cleanup-warnings/pypy/jit/backend/model.py pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py Log: Move mutable stuff into CPUMutableContainer and _freeze_ the CPU. Should speed up stuff a bit (maybe) as well Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py Wed Mar 3 04:22:03 2010 @@ -14,6 +14,9 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr +class CPUMutableContainer(object): + _overflow_flag = False + class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts @@ -21,6 +24,7 @@ def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): + self.mutable = CPUMutableContainer() assert type(opts) is not bool self.opts = opts @@ -52,12 +56,22 @@ self._setup_on_leave_jitted_translated() else: self._setup_on_leave_jitted_untranslated() + self.class_sizes = {} + + def set_overflow_flag(self, val): + self.mutable._overflow_flag = val + + def get_overflow_error(self): + return self.mutable._overflow_flag + + def _freeze_(self): + return True def setup(self): pass def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes + self.class_sizes.update(class_sizes) def _setup_prebuilt_error(self, prefix, Class): if self.rtyper is not None: # normal case @@ -107,8 +121,8 @@ v_i = _exception_emulator[1] _exception_emulator[0] = 0 _exception_emulator[1] = 0 - self.saved_exception = tp_i - self.saved_exc_value = self._cast_int_to_gcref(v_i) + self.mutable.saved_exception = tp_i + self.mutable.saved_exc_value = self._cast_int_to_gcref(v_i) self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -135,8 +149,8 @@ # from now on, the state is again consistent -- no more RPython # exception is set. The following code produces a write barrier # in the assignment to self.saved_exc_value, as needed. - self.saved_exception = exception - self.saved_exc_value = exc_value + self.mutable.saved_exception = exception + self.mutable.saved_exc_value = exc_value self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -174,14 +188,14 @@ return rffi.cast(lltype.Signed, f) def get_exception(self): - return self.saved_exception + return self.mutable.saved_exception def get_exc_value(self): - return self.saved_exc_value + return self.mutable.saved_exc_value def clear_exception(self): - self.saved_exception = 0 - self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.mutable.saved_exception = 0 + self.mutable.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) # ------------------- helpers and descriptions -------------------- Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/model.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/model.py Wed Mar 3 04:22:03 2010 @@ -10,6 +10,8 @@ CallDescrClass = None # a base class for all CallDescrs + _overflow_flag = False + def __init__(self): self.fail_descr_list = [] @@ -115,6 +117,12 @@ def get_zero_division_error(self): raise NotImplementedError + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, val): + self._overflow_flag = val + @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py Wed Mar 3 04:22:03 2010 @@ -264,8 +264,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu._overflow_flag: # overflow detected - del builder.cpu._overflow_flag + if builder.cpu.get_overflow_flag(): # overflow detected + builder.cpu.set_overflow_flag(False) op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py Wed Mar 3 04:22:03 2010 @@ -145,7 +145,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_sub_ovf(cpu, box1, box2): @@ -158,7 +158,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_mul_ovf(cpu, box1, box2): @@ -171,7 +171,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) # ---------- Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py Wed Mar 3 04:22:03 2010 @@ -1899,8 +1899,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu._overflow_flag: - self.cpu._overflow_flag = False + if self.cpu.get_overflow_flag(): + self.cpu.set_overflow_flag(False) frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From fijal at codespeak.net Wed Mar 3 05:00:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 05:00:56 +0100 (CET) Subject: [pypy-svn] r71697 - in pypy/branch/cleanup-warnings/pypy/jit: backend backend/llgraph backend/llsupport metainterp Message-ID: <20100303040056.57396282BD5@codespeak.net> Author: fijal Date: Wed Mar 3 05:00:52 2010 New Revision: 71697 Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llgraph/runner.py pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py pypy/branch/cleanup-warnings/pypy/jit/backend/model.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizefindnode.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py Log: Fight a bit harder with annotation warnings - I think they're mostly gone by now Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/llgraph/runner.py Wed Mar 3 05:00:52 2010 @@ -75,6 +75,8 @@ supports_floats = True CallDescrClass = Descr + ArrayDescrClass = Descr + FieldDescrClass = Descr def __init__(self, rtyper, stats=None, opts=None, translate_support_code=False, @@ -725,6 +727,8 @@ def get_extra_info(self): return self.extrainfo +OOtypeCPU.CallDescrClass = StaticMethDescr + class MethDescr(history.AbstractMethDescr): callmeth = None @@ -844,6 +848,8 @@ def __repr__(self): return '' % self.fieldname +OOtypeCPU.FieldDescrClass = FieldDescr +OOtypeCPU.ArrayDescrClass = TypeDescr # ____________________________________________________________ Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py Wed Mar 3 05:00:52 2010 @@ -21,6 +21,8 @@ from pypy.jit.metainterp.typesystem import llhelper as ts CallDescrClass = BaseCallDescr + FieldDescrClass = BaseFieldDescr + ArrayDescrClass = BaseArrayDescr def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/model.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/model.py Wed Mar 3 05:00:52 2010 @@ -9,6 +9,8 @@ done_with_this_frame_int_v = -1 CallDescrClass = None # a base class for all CallDescrs + ArrayDescrClass = None + FieldDescrClass = None _overflow_flag = False Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizefindnode.py Wed Mar 3 05:00:52 2010 @@ -193,7 +193,9 @@ return # var-sized arrays are not virtual arraynode = InstanceNode() arraynode.arraysize = lengthbox.getint() - arraynode.arraydescr = op.descr + descr = op.descr + assert isinstance(descr, self.cpu.ArrayDescrClass) + arraynode.arraydescr = descr self.nodes[op.result] = arraynode def find_nodes_ARRAYLEN_GC(self, op): @@ -223,7 +225,7 @@ fieldnode.mark_escaped() return # nothing to be gained from tracking the field field = op.descr - assert isinstance(field, AbstractValue) + assert isinstance(field, self.cpu.FieldDescrClass) if instnode.curfields is None: instnode.curfields = {} instnode.curfields[field] = fieldnode @@ -234,7 +236,7 @@ if instnode.escaped: return # nothing to be gained from tracking the field field = op.descr - assert isinstance(field, AbstractValue) + assert isinstance(field, self.cpu.FieldDescrClass) if instnode.curfields is not None and field in instnode.curfields: fieldnode = instnode.curfields[field] elif instnode.origfields is not None and field in instnode.origfields: @@ -384,6 +386,7 @@ # uninitialized after a guard failure. node = self.node_fromstart specnode = self.intersect(node, d[ofs]) + assert isinstance(ofs, self.cpu.FieldDescrClass) fields.append((ofs, specnode)) return fields Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Wed Mar 3 05:00:52 2010 @@ -172,6 +172,8 @@ def _make_virtual(self, modifier): raise NotImplementedError("abstract base") + def _really_force(self): + raise NotImplementedError("abstract base") def get_fielddescrlist_cache(cpu): if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'): @@ -358,7 +360,7 @@ def _setup_virtual_node_1(self, optimizer, box): raise NotImplementedError def teardown_virtual_node(self, optimizer, value, newexitargs): - assert value.is_virtual() + assert isinstance(value, AbstractVirtualStructValue) for ofs, subspecnode in self.fields: subvalue = value.getfield(ofs, optimizer.new_const(ofs)) subspecnode.teardown_virtual_node(optimizer, subvalue, newexitargs) @@ -381,7 +383,7 @@ vvalueitem = optimizer.getvalue(subbox) vvalue.setitem(index, vvalueitem) def teardown_virtual_node(self, optimizer, value, newexitargs): - assert value.is_virtual() + assert isinstance(value, VArrayValue) for index in range(len(self.items)): subvalue = value.getitem(index) subspecnode = self.items[index] @@ -455,6 +457,7 @@ return vvalue def make_varray(self, arraydescr, size, box, source_op=None): + assert isinstance(arraydescr, self.cpu.ArrayDescrClass) vvalue = VArrayValue(self, arraydescr, size, box, source_op) self.make_equal_to(box, vvalue) return vvalue @@ -819,7 +822,7 @@ value = self.getvalue(op.args[0]) if value.is_virtual(): # optimizefindnode should ensure that fieldvalue is found - assert isinstance(value, AbstractVirtualValue) + assert isinstance(value, AbstractVirtualStructValue) fieldvalue = value.getfield(op.descr, None) assert fieldvalue is not None self.make_equal_to(op.result, fieldvalue) @@ -835,6 +838,7 @@ value = self.getvalue(op.args[0]) fieldvalue = self.getvalue(op.args[1]) if value.is_virtual(): + assert isinstance(value, AbstractVirtualStructValue) value.setfield(op.descr, fieldvalue) else: value.ensure_nonnull() @@ -861,6 +865,7 @@ def optimize_ARRAYLEN_GC(self, op): value = self.getvalue(op.args[0]) if value.is_virtual(): + assert isinstance(value, VArrayValue) self.make_constant_int(op.result, value.getlength()) else: value.ensure_nonnull() @@ -871,6 +876,7 @@ if value.is_virtual(): indexbox = self.get_constant_box(op.args[1]) if indexbox is not None: + assert isinstance(value, VArrayValue) itemvalue = value.getitem(indexbox.getint()) self.make_equal_to(op.result, itemvalue) return @@ -884,6 +890,7 @@ def optimize_SETARRAYITEM_GC(self, op): value = self.getvalue(op.args[0]) if value.is_virtual(): + assert isinstance(value, VArrayValue) indexbox = self.get_constant_box(op.args[1]) if indexbox is not None: value.setitem(indexbox.getint(), self.getvalue(op.args[2])) @@ -1032,7 +1039,9 @@ if opnum == rop.CALL_ASSEMBLER: effectinfo = None else: - effectinfo = op.descr.get_extra_info() + descr = op.descr + assert isinstance(descr, self.optimizer.cpu.CallDescrClass) + effectinfo = descr.get_extra_info() if effectinfo is not None: # XXX we can get the wrong complexity here, if the lists # XXX stored on effectinfo are large Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py Wed Mar 3 05:00:52 2010 @@ -396,7 +396,8 @@ return tagged_list_eq(self.fieldnums, fieldnums) def set_content(self, fieldnums): self.fieldnums = fieldnums - + def debug_prints(self): + raise NotImplementedError class AbstractVirtualStructInfo(AbstractVirtualInfo): def __init__(self, fielddescrs): From fijal at codespeak.net Wed Mar 3 05:25:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 05:25:16 +0100 (CET) Subject: [pypy-svn] r71698 - in pypy/branch/cleanup-warnings/pypy/jit: backend/x86 metainterp Message-ID: <20100303042516.D1636282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 05:25:13 2010 New Revision: 71698 Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Log: Store some attributes by default, so rtyper won't complain Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py Wed Mar 3 05:25:13 2010 @@ -100,6 +100,7 @@ mc2 = None mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE _float_constants = None + _regalloc = None def __init__(self, cpu, translate_support_code=False, failargs_limit=1000): Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py Wed Mar 3 05:25:13 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.objectmodel import we_are_translated -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile from pypy.jit.backend.x86.assembler import Assembler386 from pypy.jit.backend.x86.regalloc import FORCE_INDEX_OFS from pypy.jit.backend.x86.profagent import ProfileAgent @@ -141,3 +141,19 @@ import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(CPU) + +# silence warnings + +history.LoopToken._x86_param_depth = 0 +history.LoopToken._x86_arglocs = (None, None) +history.LoopToken._x86_frame_depth = 0 +history.LoopToken._x86_bootstrap_code = 0 +history.LoopToken._x86_direct_bootstrap_code = 0 +history.LoopToken._x86_failure_recovery_bytecode = 0 +history.LoopToken._x86_adr_jump_offset = 0 +history.LoopToken._x86_loop_code = 0 +history.LoopToken._x86_current_depths = (0, 0) + +compile._DoneWithThisFrameDescr._x86_current_depths = (0, 0) +compile._DoneWithThisFrameDescr._x86_failure_recovery_bytecode = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset = 0 Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py Wed Mar 3 05:25:13 2010 @@ -685,6 +685,7 @@ terminating = False # see TerminatingLoopToken in compile.py # specnodes = ... # and more data specified by the backend when the loop is compiled + number = 0 def __init__(self, number=0): self.number = number @@ -864,6 +865,7 @@ compiled_count = 0 enter_count = 0 aborted_count = 0 + history = None def __init__(self): self.loops = [] Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Wed Mar 3 05:25:13 2010 @@ -47,6 +47,7 @@ last_guard_index = -1 level = LEVEL_UNKNOWN + known_class = None def __init__(self, box): self.box = box From fijal at codespeak.net Wed Mar 3 06:59:37 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 06:59:37 +0100 (CET) Subject: [pypy-svn] r71699 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100303055937.A6716282BD5@codespeak.net> Author: fijal Date: Wed Mar 3 06:59:30 2010 New Revision: 71699 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: fix the test (situation did improve) Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Wed Mar 3 06:59:30 2010 @@ -474,7 +474,6 @@ ''', 143, ([1000], 1000 * 999 / 2)) bytecode, = self.get_by_bytecode("BINARY_SUBSCR") assert bytecode.get_opnames("guard") == [ - "guard_isnull", # check that the range list is not forced "guard_false", # check that the index is >= 0 "guard_false", # check that the index is lower than the current length ] From arigo at codespeak.net Wed Mar 3 10:12:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 10:12:48 +0100 (CET) Subject: [pypy-svn] r71700 - pypy/build/bot2/pypybuildbot Message-ID: <20100303091248.32604282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 10:12:44 2010 New Revision: 71700 Modified: pypy/build/bot2/pypybuildbot/master.py Log: List cobra too. Wyvern died. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Mar 3 10:12:44 2010 @@ -122,7 +122,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["wyvern"], + "slavenames": ["wyvern", "cobra"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'own' @@ -176,7 +176,7 @@ 'category' : 'jit', }, {"name": JITONLYLINUX32, - "slavenames": ["wyvern"], + "slavenames": ["wyvern", "cobra"], "builddir": JITONLYLINUX32, "factory": pypyJitOnlyOwnTestFactory, "category": 'own' From cfbolz at codespeak.net Wed Mar 3 10:45:24 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 3 Mar 2010 10:45:24 +0100 (CET) Subject: [pypy-svn] r71702 - pypy/extradoc/planning Message-ID: <20100303094524.1AA4E282BD4@codespeak.net> Author: cfbolz Date: Wed Mar 3 10:45:22 2010 New Revision: 71702 Modified: pypy/extradoc/planning/jit.txt Log: clean up a bit more, some of these things are not done, and some are meta-points that I want to keep as remainders Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Wed Mar 3 10:45:22 2010 @@ -18,12 +18,11 @@ _trace_and_drag_out_of_nursery. Requires thinking about card-marking GC, which is hard, postpone -- improve tracing/blackholing speed (?) +- improve tracing/blackholing speed Essential, especially blackholing in translate.py, as well as html5lib. - some guards will always fail if they ever start failing (e.g. the class version tag). Do something more clever about it. - DONE? Python interpreter: @@ -34,8 +33,6 @@ - put the class into the structure to get only one promote when using an instance -- look why module.x does two calls to _lookup_where FIXED? - - this example: http://paste.pocoo.org/show/181319/ showcases a problem that works fine as long as you not present a combination of oldstyle and newstyle classes. If you however present @@ -77,7 +74,7 @@ wishlist: - the checks that look whether profiling/tracing in the Python interpreter is - enabled look expensive. Do we want to do something about them? DONE? + enabled look expensive. Do we want to do something about them? @@ -85,9 +82,9 @@ META ----- -- stability! DONE? +- stability! -- keep test coverage in check DONE? +- keep test coverage in check - prevent too much method and fields demoting in the jit @@ -119,15 +116,10 @@ Benchmarks: they live at svn+ssh://codespeak.net/svn/pypy/benchmarks + ootype discussion ------------------ - try to unify interfaces to make doing the right thing for ootype easier - different constraints for different groups of people - what to do with ootype jit support after Anto finished his PhD? - - -memory usage ------------- - -part here was out of date a lot. From arigo at codespeak.net Wed Mar 3 10:47:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 10:47:50 +0100 (CET) Subject: [pypy-svn] r71703 - pypy/trunk/pypy/doc Message-ID: <20100303094750.4704E282BE0@codespeak.net> Author: arigo Date: Wed Mar 3 10:47:47 2010 New Revision: 71703 Modified: pypy/trunk/pypy/doc/getting-started-python.txt Log: Add "as of March 2010". Modified: pypy/trunk/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started-python.txt (original) +++ pypy/trunk/pypy/doc/getting-started-python.txt Wed Mar 3 10:47:47 2010 @@ -67,8 +67,8 @@ possibly replacing ``--opt=jit`` with another `optimization level`_ of your choice like ``--opt=2`` if you do not want the included JIT - compiler. (The default level so far is 2. Do not use ``--opt=jit`` - on something else than Intel **32-bit** machines.) + compiler. (As of March 2010, the default level is ``--opt=2``, and + ``--opt=jit`` requires an Intel **32-bit** environment.) .. _`optimization level`: config/opt.html From arigo at codespeak.net Wed Mar 3 10:54:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 10:54:51 +0100 (CET) Subject: [pypy-svn] r71704 - pypy/extradoc/planning Message-ID: <20100303095451.8B55E282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 10:54:49 2010 New Revision: 71704 Modified: pypy/extradoc/planning/jit.txt Log: Mention branch/guard-value-counting-2. Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Wed Mar 3 10:54:49 2010 @@ -23,6 +23,8 @@ - some guards will always fail if they ever start failing (e.g. the class version tag). Do something more clever about it. + (already done a hack that helps: don't compile more guard_value's + if the value guarded for keeps changing fast enough: r71527) Python interpreter: From arigo at codespeak.net Wed Mar 3 11:28:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 11:28:34 +0100 (CET) Subject: [pypy-svn] r71705 - pypy/build/bot2/pypybuildbot Message-ID: <20100303102834.253F4282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 11:28:32 2010 New Revision: 71705 Modified: pypy/build/bot2/pypybuildbot/master.py Log: While we are having troubles with both wyvern and cobra, use bigdogvm1 for all builds. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Mar 3 11:28:32 2010 @@ -122,7 +122,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["bigdogvm1"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'own' @@ -134,19 +134,19 @@ "category": 'mac' }, {"name": APPLVLLINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["bigdogvm1"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'applevel' }, {"name": STACKLESSAPPLVLLINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["bigdogvm1"], "builddir": STACKLESSAPPLVLLINUX32, "factory": pypyStacklessTranslatedAppLevelTestFactory, "category": 'stackless' }, {"name": OJITLINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["bigdogvm1"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'applevel' @@ -176,7 +176,7 @@ 'category' : 'jit', }, {"name": JITONLYLINUX32, - "slavenames": ["wyvern", "cobra"], + "slavenames": ["bigdogvm1"], "builddir": JITONLYLINUX32, "factory": pypyJitOnlyOwnTestFactory, "category": 'own' From arigo at codespeak.net Wed Mar 3 15:45:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 15:45:15 +0100 (CET) Subject: [pypy-svn] r71706 - pypy/trunk/pypy/translator/jvm/test Message-ID: <20100303144515.64653282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 15:45:12 2010 New Revision: 71706 Modified: pypy/trunk/pypy/translator/jvm/test/test_builtin.py Log: Also skip this test elsewhere. Modified: pypy/trunk/pypy/translator/jvm/test/test_builtin.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/test/test_builtin.py (original) +++ pypy/trunk/pypy/translator/jvm/test/test_builtin.py Wed Mar 3 15:45:12 2010 @@ -29,7 +29,7 @@ def test_os_access(self): from socket import gethostname - if gethostname() == 'wyvern': + if 1: # gethostname() == 'wyvern': py.test.skip('bug in JDK when run headless: ' + 'http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705') BaseTestBuiltin.test_os_access(self) From arigo at codespeak.net Wed Mar 3 15:53:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 15:53:53 +0100 (CET) Subject: [pypy-svn] r71707 - in pypy/trunk/pypy/translator: c/test platform Message-ID: <20100303145353.9A373282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 15:53:51 2010 New Revision: 71707 Modified: pypy/trunk/pypy/translator/c/test/test_standalone.py pypy/trunk/pypy/translator/platform/maemo.py Log: Fix tests. 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 Wed Mar 3 15:53:51 2010 @@ -398,7 +398,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: ValueError' + idx = lines.index('Fatal RPython error: ValueError') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' @@ -408,7 +409,8 @@ out2, err2 = cbuilder.cmdexec("x", expect_crash=True) assert out2.strip() == '' lines2 = err2.strip().splitlines() - assert lines2[-1] == 'Fatal RPython error: KeyError' + idx = lines2.index('Fatal RPython error: KeyError') # assert found + lines2 = lines2[:idx+1] l0, l1, l2 = lines2[-4:-1] assert l0 == 'RPython traceback:' assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) @@ -435,7 +437,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == 'done.' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: KeyError' + idx = lines.index('Fatal RPython error: KeyError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -471,7 +474,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == 'done.' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: KeyError' + idx = lines.index('Fatal RPython error: KeyError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -506,7 +510,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: ValueError' + idx = lines.index('Fatal RPython error: ValueError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -522,7 +527,7 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'in pypy_g_RPyRaiseException: AssertionError' + assert 'in pypy_g_RPyRaiseException: AssertionError' in lines def test_assertion_error_nondebug(self): def g(x): @@ -539,7 +544,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: AssertionError' + idx = lines.index('Fatal RPython error: AssertionError') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' @@ -556,7 +562,7 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'in pypy_g_entry_point: foobar' + assert 'in pypy_g_entry_point: foobar' in lines def test_ll_assert_error_nondebug(self): py.test.skip("implement later, maybe: tracebacks even with ll_assert") @@ -574,7 +580,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'PyPy assertion failed: foobar' + idx = lines.index('PyPy assertion failed: foobar') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' Modified: pypy/trunk/pypy/translator/platform/maemo.py ============================================================================== --- pypy/trunk/pypy/translator/platform/maemo.py (original) +++ pypy/trunk/pypy/translator/platform/maemo.py Wed Mar 3 15:53:51 2010 @@ -1,11 +1,12 @@ -import py +import py, os 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(): + # in order to work, that file must exist and be executable by us + if not os.access('/scratchbox/login', os.X_OK): py.test.skip("No scratchbox detected") class Maemo(Linux): From arigo at codespeak.net Wed Mar 3 18:13:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 3 Mar 2010 18:13:42 +0100 (CET) Subject: [pypy-svn] r71711 - pypy/branch/jit-sandbox/pypy/rlib Message-ID: <20100303171342.C0785282BD4@codespeak.net> Author: arigo Date: Wed Mar 3 18:13:40 2010 New Revision: 71711 Modified: pypy/branch/jit-sandbox/pypy/rlib/rmmap.py Log: Documentation. Modified: pypy/branch/jit-sandbox/pypy/rlib/rmmap.py ============================================================================== --- pypy/branch/jit-sandbox/pypy/rlib/rmmap.py (original) +++ pypy/branch/jit-sandbox/pypy/rlib/rmmap.py Wed Mar 3 18:13:40 2010 @@ -636,6 +636,10 @@ hint = Hint() def alloc(map_size): + """Allocate memory. This is intended to be used by the JIT, + so the memory has the executable bit set and gets allocated + internally in case of a sandboxed process. + """ flags = MAP_PRIVATE | MAP_ANONYMOUS prot = PROT_EXEC | PROT_READ | PROT_WRITE hintp = rffi.cast(PTR, hint.pos) @@ -748,6 +752,11 @@ def alloc(map_size): + """Allocate memory. This is intended to be used by the JIT, + so the memory has the executable bit set. + XXX implement me: it should get allocated internally in + case of a sandboxed process + """ null = lltype.nullptr(rffi.VOIDP.TO) res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) From fijal at codespeak.net Wed Mar 3 18:38:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 18:38:51 +0100 (CET) Subject: [pypy-svn] r71712 - in pypy/trunk/pypy: jit/backend/x86 rlib rlib/rsre translator/sandbox translator/sandbox/test Message-ID: <20100303173851.285D4282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 18:38:49 2010 New Revision: 71712 Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py pypy/trunk/pypy/jit/backend/x86/valgrind.py pypy/trunk/pypy/rlib/rmmap.py pypy/trunk/pypy/rlib/rsre/_rsre_platform.py pypy/trunk/pypy/translator/sandbox/sandlib.py pypy/trunk/pypy/translator/sandbox/test/test_sandbox.py Log: Merge jit-sandbox branch, that enables jit to cooperate with sandbox, minor issues only Modified: pypy/trunk/pypy/jit/backend/x86/codebuf.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/codebuf.py (original) +++ pypy/trunk/pypy/jit/backend/x86/codebuf.py Wed Mar 3 18:38:49 2010 @@ -155,4 +155,5 @@ separate_module_sources = ['void PYPY_NO_OP(void) {}'], ) ensure_sse2_floats = rffi.llexternal('PYPY_NO_OP', [], lltype.Void, - compilation_info=_sse2_eci) + compilation_info=_sse2_eci, + sandboxsafe=True) Modified: pypy/trunk/pypy/jit/backend/x86/valgrind.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/valgrind.py (original) +++ pypy/trunk/pypy/jit/backend/x86/valgrind.py Wed Mar 3 18:38:49 2010 @@ -20,7 +20,8 @@ [llmemory.Address, lltype.Signed], lltype.Void, compilation_info=eci, - _nowrapper=True) + _nowrapper=True, + sandboxsafe=True) # ____________________________________________________________ Modified: pypy/trunk/pypy/rlib/rmmap.py ============================================================================== --- pypy/trunk/pypy/rlib/rmmap.py (original) +++ pypy/trunk/pypy/rlib/rmmap.py Wed Mar 3 18:38:49 2010 @@ -91,26 +91,32 @@ _ACCESS_DEFAULT, ACCESS_READ, ACCESS_WRITE, ACCESS_COPY = range(4) def external(name, args, result): - return rffi.llexternal(name, args, result, - compilation_info=CConfig._compilation_info_) + unsafe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_) + safe = rffi.llexternal(name, args, result, + compilation_info=CConfig._compilation_info_, + sandboxsafe=True, threadsafe=False) + return unsafe, safe def winexternal(name, args, result): return rffi.llexternal(name, args, result, compilation_info=CConfig._compilation_info_, calling_conv='win') PTR = rffi.CCHARP -c_memmove = external('memmove', [PTR, PTR, size_t], lltype.Void) +c_memmove, _ = external('memmove', [PTR, PTR, size_t], lltype.Void) if _POSIX: has_mremap = cConfig['has_mremap'] - c_mmap = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, + c_mmap, c_mmap_safe = external('mmap', [PTR, size_t, rffi.INT, rffi.INT, rffi.INT, off_t], PTR) - c_munmap = external('munmap', [PTR, size_t], rffi.INT) - c_msync = external('msync', [PTR, size_t, rffi.INT], rffi.INT) + c_munmap, c_munmap_safe = external('munmap', [PTR, size_t], rffi.INT) + c_msync, _ = external('msync', [PTR, size_t, rffi.INT], rffi.INT) if has_mremap: - c_mremap = external('mremap', [PTR, size_t, size_t, rffi.ULONG], PTR) + c_mremap, _ = external('mremap', + [PTR, size_t, size_t, rffi.ULONG], PTR) - _get_page_size = external('getpagesize', [], rffi.INT) + # this one is always safe + _, _get_page_size = external('getpagesize', [], rffi.INT) def _get_error_no(): return rposix.get_errno() @@ -630,17 +636,21 @@ hint = Hint() def alloc(map_size): + """Allocate memory. This is intended to be used by the JIT, + so the memory has the executable bit set and gets allocated + internally in case of a sandboxed process. + """ flags = MAP_PRIVATE | MAP_ANONYMOUS prot = PROT_EXEC | PROT_READ | PROT_WRITE hintp = rffi.cast(PTR, hint.pos) - res = c_mmap(hintp, map_size, prot, flags, -1, 0) + res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0) if res == rffi.cast(PTR, -1): raise MemoryError hint.pos += map_size return res alloc._annenforceargs_ = (int,) - free = c_munmap + free = c_munmap_safe elif _MS_WINDOWS: def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT): @@ -742,6 +752,11 @@ def alloc(map_size): + """Allocate memory. This is intended to be used by the JIT, + so the memory has the executable bit set. + XXX implement me: it should get allocated internally in + case of a sandboxed process + """ null = lltype.nullptr(rffi.VOIDP.TO) res = VirtualAlloc(null, map_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE) Modified: pypy/trunk/pypy/rlib/rsre/_rsre_platform.py ============================================================================== --- pypy/trunk/pypy/rlib/rsre/_rsre_platform.py (original) +++ pypy/trunk/pypy/rlib/rsre/_rsre_platform.py Wed Mar 3 18:38:49 2010 @@ -10,7 +10,8 @@ return rffi.llexternal(name, args, result, compilation_info=eci, **kwds) tolower = external('tolower', [lltype.Signed], lltype.Signed, - oo_primitive='tolower') + oo_primitive='tolower', + sandboxsafe=True) isalnum = external('isalnum', [lltype.Signed], lltype.Signed, - oo_primitive='isalnum') + oo_primitive='isalnum', sandboxsafe=True) Modified: pypy/trunk/pypy/translator/sandbox/sandlib.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/sandlib.py (original) +++ pypy/trunk/pypy/translator/sandbox/sandlib.py Wed Mar 3 18:38:49 2010 @@ -10,7 +10,7 @@ from pypy.rpython.module.ll_os_stat import s_StatResult from pypy.tool.ansi_print import AnsiLog from pypy.rlib.rarithmetic import r_longlong -from py.compat import subprocess +import subprocess from pypy.tool.killsubprocess import killsubprocess class MyAnsiLog(AnsiLog): 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 Wed Mar 3 18:38:49 2010 @@ -1,6 +1,7 @@ import py import sys, os, time import struct +import subprocess from pypy.rpython.lltypesystem import rffi from pypy.translator.interactive import Translation @@ -19,8 +20,8 @@ write_message(g, result, resulttype) g.flush() -def compile(f): - t = Translation(f, backend='c', standalone=True, sandbox=True, gc='ref') +def compile(f, gc='ref'): + t = Translation(f, backend='c', standalone=True, sandbox=True, gc=gc) return str(t.compile()) @@ -131,6 +132,72 @@ f.close() assert tail == "" +def test_hybrid_gc(): + def entry_point(argv): + l = [] + for i in range(int(argv[1])): + l.append("x" * int(argv[2])) + return int(len(l) > 1000) + + exe = compile(entry_point, gc='hybrid') + pipe = subprocess.Popen([exe, '10', '10000'], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GENERATIONGC_NURSERY",), None) + expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420), OSError(5232, "xyz")) + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + +def test_safe_alloc(): + from pypy.rlib.rmmap import alloc, free + + def entry_point(argv): + one = alloc(1024) + free(one, 1024) + return 0 + + exe = compile(entry_point) + pipe = subprocess.Popen([exe], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + +def test_unsafe_mmap(): + py.test.skip("Since this stuff is unimplemented, it won't work anyway " + "however, the day it starts working, it should pass test") + from pypy.rlib.rmmap import mmap + + def entry_point(argv): + try: + res = mmap(0, 1024) + except OSError: + return 0 + return 1 + + exe = compile(entry_point) + pipe = subprocess.Popen([exe], stdout=subprocess.PIPE, + stdin=subprocess.PIPE) + g = pipe.stdin + f = pipe.stdout + expect(f, g, "mmap", ARGS, OSError(1, "xyz")) + g.close() + tail = f.read() + f.close() + assert tail == "" + rescode = pipe.wait() + assert rescode == 0 + class TestPrintedResults: def run(self, entry_point, args, expected): From fijal at codespeak.net Wed Mar 3 19:03:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 3 Mar 2010 19:03:07 +0100 (CET) Subject: [pypy-svn] r71713 - pypy/branch/jit-sandbox Message-ID: <20100303180307.39C6A282BD4@codespeak.net> Author: fijal Date: Wed Mar 3 19:03:06 2010 New Revision: 71713 Removed: pypy/branch/jit-sandbox/ Log: remove merged branch From dan at codespeak.net Wed Mar 3 22:02:18 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Wed, 3 Mar 2010 22:02:18 +0100 (CET) Subject: [pypy-svn] r71715 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100303210218.4E58D282BD5@codespeak.net> Author: dan Date: Wed Mar 3 22:02:08 2010 New Revision: 71715 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Added a few tests for interplevel code. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Wed Mar 3 22:02:08 2010 @@ -19,49 +19,6 @@ def coerce_float32(space, w_x): return unwrap_float32(space, space.float(w_x)) -def typecode(space, w_type): - try: - assert isinstance(w_type, DynamicType) - return w_type.code - except AssertionError, e: pass - - try: - return space.str_w(w_type) - except OperationError, e: - typecode_mapping = { - space.w_int: 'i', - space.w_float: 'd', - } - try: - return typecode_mapping[w_type] - except IndexError, e: - raise OperationError(space.w_TypeError, - space.wrap("Can't understand type.")) - -result_types = { - ('i', 'i'): 'i', - ('i', 'd'): 'd', - ('d', 'i'): 'd', - ('d', 'd'): 'd', - } - -def result_mapping(space, types): - types = (typecode(space, types[0]), - typecode(space, types[1])) - return result_types[types] - -def iterable_type(space, w_xs): - xs = space.fixedview(w_xs) - result_type = 'i' - for i in range(len(xs)): - try: - atype = iterable_type(space, xs[i]) - except OperationError, e: - if not e.match(space, space.w_TypeError): - raise - atype = typecode(space, space.type(xs[i])) - result_type = result_types[(result_type, atype)] - return result_type def create_factory(result_factory): def factory(t): @@ -81,23 +38,68 @@ try: code = space.str_w(w_x) if self.code == code: - return space.wrap(True) + return space.w_True elif self.name == code: - return space.wrap(True) + return space.w_True else: - return space.wrap(False) + return space.w_False except OperationError, e: - return space.wrap(False) + return space.w_False except TypeError, e: - return space.wrap(False) #FIXME: need to throw applevel type error + return space.w_False #FIXME: need to throw applevel type error descr_eq.unwrap_spec = ['self', ObjSpace, W_Root] DynamicType.typedef = TypeDef('dtype', __eq__ = interp2app(DynamicType.descr_eq), ) class DynamicTypes(object): + result_types = { + ('i', 'i'): 'i', + ('i', 'd'): 'd', + ('d', 'i'): 'd', + ('d', 'd'): 'd', + } + def __init__(self): self.dtypes = {} + + def typecode(self, space, w_type): + try: + assert isinstance(w_type, DynamicType) + return w_type.code + except AssertionError, e: pass + + try: + return space.str_w(w_type) + except OperationError, e: + typecode_mapping = { + space.w_int: 'i', + space.w_float: 'd', + } + try: + return typecode_mapping[w_type] + except IndexError, e: + raise OperationError(space.w_TypeError, + space.wrap("Can't understand type.")) + + def result_mapping(self, space, types): + types = (self.typecode(space, types[0]), + self.typecode(space, types[1])) + return self.result_types[types] + + def iterable_type(self, space, w_xs): + xs = space.fixedview(w_xs) + result_type = 'i' + for i in range(len(xs)): + try: + atype = self.iterable_type(space, xs[i]) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + atype = self.typecode(space, space.type(xs[i])) + result_type = self.result_types[(result_type, atype)] + return result_type + def verify_dtype_dict(self, space): if not self.dtypes: self.dtypes.update( @@ -116,11 +118,22 @@ t = space.str_w(w_type) except OperationError, e: if e.match(space, space.w_TypeError): - t = typecode(space, w_type) + t = self.typecode(space, w_type) else: raise return self.retrieve_dtype(space, t) + def sdarray(self, space, length, w_dtype): + from pypy.module.micronumpy.sdarray import sdresult + return sdresult(self.typecode(space))(space, length, w_dtype) + + def mdarray(self, space, shape, w_dtype): + from pypy.module.micronumpy.mdarray import mdresult + return mdresult(self.typecode(space))(space, shape, w_dtype) + dtypes = DynamicTypes() +iterable_type = dtypes.iterable_type +typecode = dtypes.typecode +result_mapping = dtypes.result_mapping get_dtype = dtypes.get_dtype retrieve_dtype = dtypes.retrieve_dtype Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Wed Mar 3 22:02:08 2010 @@ -244,5 +244,40 @@ assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) +class TestDType(object): + def test_lookups(self, space): + from pypy.module.micronumpy.dtype import retrieve_dtype + from pypy.module.micronumpy.dtype import get_dtype + a = get_dtype(space, space.wrap('i')) + b = get_dtype(space, space.wrap('d')) - + assert a == retrieve_dtype(space, 'i') + assert b == retrieve_dtype(space, 'd') + + def test_result_types(self, space): + from pypy.module.micronumpy.dtype import get_dtype + from pypy.module.micronumpy.dtype import result_mapping + w_typecode_a = space.wrap('i') + w_typecode_b = space.wrap('d') + a = get_dtype(space, w_typecode_a) + b = get_dtype(space, w_typecode_b) + + assert 'i' == result_mapping(space, (w_typecode_a, w_typecode_a)) + assert 'd' == result_mapping(space, (w_typecode_b, w_typecode_a)) + assert 'd' == result_mapping(space, (w_typecode_a, w_typecode_b)) + assert 'd' == result_mapping(space, (w_typecode_b, w_typecode_b)) + + def test_iterable_type(self, space): + from pypy.module.micronumpy.dtype import iterable_type + w_int = space.wrap(1) + w_float = space.wrap(2.0) + + data = [(space.wrap([1, 2, 3, 4, 5]), 'i'), + (space.wrap([1, 2, 3.0, 4, 5]), 'd'), + (space.wrap([1, 2.0, 3.0, 4, 5]), 'd'), + (space.wrap([1.0, 2, 3, 4, 5]), 'd'), + (space.wrap([1, 2, 3, 4, 5.0]), 'd'), + (space.wrap([1.0, 2, 3, 4, 5.0]), 'd')] + + for w_xs, typecode in data: + assert typecode == iterable_type(space, w_xs) From fijal at codespeak.net Thu Mar 4 01:41:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 01:41:14 +0100 (CET) Subject: [pypy-svn] r71716 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100304004114.EE815282BD7@codespeak.net> Author: fijal Date: Thu Mar 4 01:41:11 2010 New Revision: 71716 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Log: Apparently these cases are not that essential Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Thu Mar 4 01:41:11 2010 @@ -42,10 +42,13 @@ elif self.name == code: return space.w_True else: + xxx return space.w_False except OperationError, e: + xxx return space.w_False except TypeError, e: + xxx return space.w_False #FIXME: need to throw applevel type error descr_eq.unwrap_spec = ['self', ObjSpace, W_Root] DynamicType.typedef = TypeDef('dtype', From getxsick at codespeak.net Thu Mar 4 02:22:44 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 02:22:44 +0100 (CET) Subject: [pypy-svn] r71717 - pypy/build/ubuntu/debian Message-ID: <20100304012244.D939E282BDC@codespeak.net> Author: getxsick Date: Thu Mar 4 02:22:42 2010 New Revision: 71717 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/rules Log: update testing section - remove redundancy, - use symlink instead of hard copy, - fix PYTHONPATH issue Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Thu Mar 4 02:22:42 2010 @@ -9,14 +9,16 @@ BINARIES=%(BINARIES)s -all: $(BINARIES) test +all: $(BINARIES) test: export TMPDIR = $(CURDIR)/tests-tmp -test: export PYTHONPATH = ".:"$(PYTHONPATH) +test: export PYTHONPATH = $(CURDIR) test: @rm -rf $(TMPDIR) mkdir $(TMPDIR) - cp build-default/usession-$$USER/testing_1/testing_1 pypy/translator/goal/pypy-c + ln -s $(CURDIR)/bin/pypy $(CURDIR)/pypy/translator/goal/pypy-c + echo $(CURDIR) + echo $(PYTHONPATH) set -e; python testrunner/runner.py \ --logfile=pytest-A.log \ --config=pypy/pytest-A.cfg \ Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Thu Mar 4 02:22:42 2010 @@ -27,6 +27,7 @@ build-arch: build-arch-stamp build-arch-stamp: Makefile $(MAKE) all + $(MAKE) test touch $@ build-indep: build-indep-stamp From getxsick at codespeak.net Thu Mar 4 02:48:00 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 02:48:00 +0100 (CET) Subject: [pypy-svn] r71718 - in pypy/trunk/pypy: lib/test2 translator/microbench/pybench Message-ID: <20100304014800.6FE6D282BD7@codespeak.net> Author: getxsick Date: Thu Mar 4 02:47:50 2010 New Revision: 71718 Modified: pypy/trunk/pypy/lib/test2/pickledtasklet.py pypy/trunk/pypy/translator/microbench/pybench/platform.py pypy/trunk/pypy/translator/microbench/pybench/pybench.py Log: update shebang to independent version Modified: pypy/trunk/pypy/lib/test2/pickledtasklet.py ============================================================================== --- pypy/trunk/pypy/lib/test2/pickledtasklet.py (original) +++ pypy/trunk/pypy/lib/test2/pickledtasklet.py Thu Mar 4 02:47:50 2010 @@ -1,3 +1,4 @@ +#!/usr/bin/env python import pickle, sys import stackless Modified: pypy/trunk/pypy/translator/microbench/pybench/platform.py ============================================================================== --- pypy/trunk/pypy/translator/microbench/pybench/platform.py (original) +++ pypy/trunk/pypy/translator/microbench/pybench/platform.py Thu Mar 4 02:47:50 2010 @@ -1,4 +1,4 @@ -#!/usr/local/bin/python +#!/usr/bin/env python """ This module tries to retrieve as much platform identifying data as possible. It makes this information available via function APIs. Modified: pypy/trunk/pypy/translator/microbench/pybench/pybench.py ============================================================================== --- pypy/trunk/pypy/translator/microbench/pybench/pybench.py (original) +++ pypy/trunk/pypy/translator/microbench/pybench/pybench.py Thu Mar 4 02:47:50 2010 @@ -1,4 +1,4 @@ -#!/usr/local/bin/python -O +#!/usr/bin/env python -O """ A Python Benchmark Suite """ From getxsick at codespeak.net Thu Mar 4 03:22:49 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 03:22:49 +0100 (CET) Subject: [pypy-svn] r71719 - in pypy/trunk/lib-python/2.5.2: plat-atheos plat-freebsd4 plat-freebsd5 plat-freebsd6 plat-freebsd7 plat-os2emx Message-ID: <20100304022249.38E43282BDC@codespeak.net> Author: getxsick Date: Thu Mar 4 03:22:28 2010 New Revision: 71719 Modified: pypy/trunk/lib-python/2.5.2/plat-atheos/regen (props changed) pypy/trunk/lib-python/2.5.2/plat-freebsd4/regen (props changed) pypy/trunk/lib-python/2.5.2/plat-freebsd5/regen (props changed) pypy/trunk/lib-python/2.5.2/plat-freebsd6/regen (props changed) pypy/trunk/lib-python/2.5.2/plat-freebsd7/regen (props changed) pypy/trunk/lib-python/2.5.2/plat-os2emx/regen (props changed) Log: set executable bit From getxsick at codespeak.net Thu Mar 4 03:51:34 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 03:51:34 +0100 (CET) Subject: [pypy-svn] r71720 - pypy/build/ubuntu/debian Message-ID: <20100304025134.1A61B282BDC@codespeak.net> Author: getxsick Date: Thu Mar 4 03:51:33 2010 New Revision: 71720 Modified: pypy/build/ubuntu/debian/rules Log: remove outdated (mostly) rules Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Thu Mar 4 03:51:33 2010 @@ -51,39 +51,9 @@ cp debian/pypy-lib.override debian/pypy-lib/usr/share/lintian/overrides/pypy-lib cp debian/pypy-dev.override debian/pypy-dev/usr/share/lintian/overrides/pypy-dev dh_install -i - find debian/pypy-lib -name CVS | xargs rm -rf find debian/pypy-lib -name "*.pyc" | xargs rm -rf find debian/pypy-dev -name "*.pyc" | xargs rm -rf - find debian/pypy-dev/usr/share/pypy-*/pypy/translator/llvm \ - debian/pypy-lib/usr/share/pypy-*/lib-python \ - debian/pypy-dev/usr/share/pypy-*/pypy/lang/js/test/ecma \ - -type f | xargs chmod a-x - for f in `find debian/pypy-lib debian/pypy-dev -type f` ; do \ - if head -n 1 $$f | grep -q '^#!.*python' ; then \ - chmod a+x $$f ; \ - fi ; \ - done - chmod a+x debian/pypy-lib/usr/share/pypy-*/lib-python/2.5.2/plat-*/regen - for f in debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/test/test_largefile.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/test/test_largefile.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/cgi.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/bsddb/dbshelve.py \ - debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/pybench.py \ - debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/Setup.py \ - debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/Setup.py \ - debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/microbench/pybench/platform.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/app_test/test_binascii.py \ - debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/test2/pickledtasklet.py \ - ; do \ - echo "#!/usr/bin/python" > debian/tmpfile ; \ - tail -n +2 $$f >> debian/tmpfile ; \ - mv debian/tmpfile $$f ; \ - chmod a+x $$f ; \ - done rm debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE - rm debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/lang/js/commit - rm debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/pyrepl/.cvsignore - rmdir debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/js/examples/bnb/data/images/ install-arch: dh_testdir From getxsick at codespeak.net Thu Mar 4 03:55:46 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 03:55:46 +0100 (CET) Subject: [pypy-svn] r71721 - pypy/build/ubuntu/debian Message-ID: <20100304025546.A0AD4282BDC@codespeak.net> Author: getxsick Date: Thu Mar 4 03:55:45 2010 New Revision: 71721 Modified: pypy/build/ubuntu/debian/Makefile.in Log: add removing logs in clean segment Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Thu Mar 4 03:55:45 2010 @@ -53,6 +53,7 @@ rm -rf pypy/_cache rm -rf greenlet/build rm -f greenlet/_greenlet.so + rm -f pytest-A.log cpython.log pypyjit.log find . -name "*.pyc" | xargs rm -f install: all From dan at codespeak.net Thu Mar 4 08:34:06 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Thu, 4 Mar 2010 08:34:06 +0100 (CET) Subject: [pypy-svn] r71722 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100304073406.0EF6B282BD7@codespeak.net> Author: dan Date: Thu Mar 4 08:34:04 2010 New Revision: 71722 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Another two tests. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Thu Mar 4 08:34:04 2010 @@ -11,8 +11,6 @@ from pypy.module.micronumpy.dtype import unwrap_int, coerce_int from pypy.module.micronumpy.dtype import unwrap_float, coerce_float -from pypy.module.micronumpy.dtype import\ - unwrap_float32, coerce_float32, float32 from pypy.module.micronumpy.dtype import result_mapping, iterable_type from pypy.module.micronumpy.dtype import create_factory @@ -278,7 +276,6 @@ IntArray = create_sdarray(int, unwrap_int, coerce_int) FloatArray = create_sdarray(float, unwrap_float, coerce_float) -Float32Array = create_sdarray(float32, unwrap_float32, coerce_float32) GenericArray = None sdresult = create_factory({'i': IntArray, 'd': FloatArray}) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Thu Mar 4 08:34:04 2010 @@ -1,6 +1,43 @@ ? from pypy.conftest import gettestobjspace +class TestSDArray(object): + def test_unwrap(self, space): + w_int = space.wrap(1) + w_float = space.wrap(1.0) + + from pypy.interpreter.error import OperationError + def interp_raises(exceptions, f, *args, **kwargs): + try: + f(*args, **kwargs) + except OperationError, e: + for ex in exceptions: + if e.match(space, ex): + return + raise + else: + raise AssertionError("Expected one of %s to be raised" % str(exceptions)) + + from pypy.module.micronumpy.dtype import unwrap_int + assert 1 == unwrap_int(space, w_int) + interp_raises((space.w_TypeError,), unwrap_int, space, w_float) + + from pypy.module.micronumpy.dtype import unwrap_float + assert 1.0 == unwrap_float(space, w_float) + #interp_raises((space.w_TypeError,), unwrap_float, space, w_int) #er, shouldn't this raise? + + def test_coerce(self, space): + w_int = space.wrap(1) + w_float = space.wrap(1.0) + + from pypy.module.micronumpy.dtype import coerce_int + assert 1 == coerce_int(space, w_int) + assert 1 == coerce_int(space, w_float) + + from pypy.module.micronumpy.dtype import coerce_float + assert 1.0 == coerce_float(space, w_int) + assert 1.0 == coerce_float(space, w_float) + class AppTestSDArray(object): def setup_class(cls): cls.space = gettestobjspace(usemodules=('micronumpy',)) From arigo at codespeak.net Thu Mar 4 13:58:56 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Mar 2010 13:58:56 +0100 (CET) Subject: [pypy-svn] r71724 - pypy/build/bot2/pypybuildbot Message-ID: <20100304125856.D7EA0282BD7@codespeak.net> Author: arigo Date: Thu Mar 4 13:58:54 2010 New Revision: 71724 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: (iko, arigo) Tentative: kill setting the first-time property, and instead write a command that will call py.svnwcrevert only if the 'pypy' directory exist. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Mar 4 13:58:54 2010 @@ -11,38 +11,7 @@ if cmd is not None and cmd.rc == -1: return self.describe(True) + ['aborted'] return shell.ShellCommand.getText(self, cmd, results) - -class FirstTime(shell.SetProperty): - - def __init__(self, **kwds): - workdir = kwds.pop('workdir', None) - shell.SetProperty.__init__(self, description="first-time", - property="first-time", - workdir=workdir) - - -class PosixFirstTime(FirstTime): - command = "test -d pypy || echo yes" - -class WindowsFirstTime(FirstTime): - command = "if not exist pypy echo yes" - - -class CondShellCommand(ShellCmd): - - def __init__(self, **kwds): - self.cond = kwds.pop('cond', lambda props: True) - ShellCmd.__init__(self, **kwds) - - def start(self): - props = self.build.getProperties() - yes = self.cond(props) - if yes: - ShellCmd.start(self) - else: - self.setStatus(None, SUCCESS) - self.finished(SUCCESS) class Translate(ShellCmd): name = "translate" @@ -67,22 +36,15 @@ # ________________________________________________________________ -def not_first_time(props): - first_time = props.getProperty("first-time") - return not first_time - def setup_steps(platform, factory, workdir=None): if platform == "win32": - first_time_check = WindowsFirstTime() + command = "if exist pypy %s" else: - first_time_check = PosixFirstTime() - - factory.addStep(first_time_check) - factory.addStep(CondShellCommand( + command = "if [ -d pypy ]; then %s; fi" + command = command % "python py/bin/py.svnwcrevert -p.buildbot-sourcedata ." + factory.addStep(ShellCmd( description="wcrevert", - cond=not_first_time, - command = ["python", "py/bin/py.svnwcrevert", - "-p.buildbot-sourcedata", "."], + command = command, workdir = workdir, )) factory.addStep(source.SVN(baseURL="http://codespeak.net/svn/pypy/", From arigo at codespeak.net Thu Mar 4 16:19:12 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Mar 2010 16:19:12 +0100 (CET) Subject: [pypy-svn] r71729 - pypy/trunk/pypy/config Message-ID: <20100304151912.4EB68282BD7@codespeak.net> Author: arigo Date: Thu Mar 4 16:19:10 2010 New Revision: 71729 Modified: pypy/trunk/pypy/config/pypyoption.py Log: Enable 'sharingdict' and 'inlineddict' by default in O2 builds. It gives an incredible memory usage benefit and in my timings has no noticeable performance impact (less than 1% on richards). Modified: pypy/trunk/pypy/config/pypyoption.py ============================================================================== --- pypy/trunk/pypy/config/pypyoption.py (original) +++ pypy/trunk/pypy/config/pypyoption.py Thu Mar 4 16:19:10 2010 @@ -333,6 +333,9 @@ config.objspace.std.suggest(optimized_list_getitem=True) config.objspace.std.suggest(getattributeshortcut=True) config.objspace.std.suggest(newshortcut=True) + if type_system != 'ootype': + config.objspace.std.suggest(withsharingdict=True) + config.objspace.std.suggest(withinlineddict=True) # extra costly optimizations only go in level 3 if level == '3': @@ -360,10 +363,7 @@ # extra optimizations with the JIT if level == 'jit': - if type_system != 'ootype': - config.objspace.std.suggest(withsharingdict=True) config.objspace.std.suggest(withcelldict=True) - config.objspace.std.suggest(withinlineddict=True) def enable_allworkingmodules(config): From arigo at codespeak.net Thu Mar 4 16:19:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Mar 2010 16:19:22 +0100 (CET) Subject: [pypy-svn] r71730 - pypy/release/1.2.x/pypy/config Message-ID: <20100304151922.81861282BDC@codespeak.net> Author: arigo Date: Thu Mar 4 16:19:20 2010 New Revision: 71730 Modified: pypy/release/1.2.x/pypy/config/pypyoption.py Log: Merge r71729. Modified: pypy/release/1.2.x/pypy/config/pypyoption.py ============================================================================== --- pypy/release/1.2.x/pypy/config/pypyoption.py (original) +++ pypy/release/1.2.x/pypy/config/pypyoption.py Thu Mar 4 16:19:20 2010 @@ -333,6 +333,9 @@ config.objspace.std.suggest(optimized_list_getitem=True) config.objspace.std.suggest(getattributeshortcut=True) config.objspace.std.suggest(newshortcut=True) + if type_system != 'ootype': + config.objspace.std.suggest(withsharingdict=True) + config.objspace.std.suggest(withinlineddict=True) # extra costly optimizations only go in level 3 if level == '3': @@ -360,10 +363,7 @@ # extra optimizations with the JIT if level == 'jit': - if type_system != 'ootype': - config.objspace.std.suggest(withsharingdict=True) config.objspace.std.suggest(withcelldict=True) - config.objspace.std.suggest(withinlineddict=True) def enable_allworkingmodules(config): From arigo at codespeak.net Thu Mar 4 16:21:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Mar 2010 16:21:18 +0100 (CET) Subject: [pypy-svn] r71731 - pypy/build/bot2/pypybuildbot Message-ID: <20100304152118.0253C282BD7@codespeak.net> Author: arigo Date: Thu Mar 4 16:21:17 2010 New Revision: 71731 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Re-add cobra for this test run, where its 4 parallel processes are still a big advantage. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 4 16:21:17 2010 @@ -122,7 +122,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["cobra", "bigdogvm1"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'own' From fijal at codespeak.net Thu Mar 4 20:08:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:08:53 +0100 (CET) Subject: [pypy-svn] r71736 - in pypy/trunk/pypy/jit: backend backend/llsupport backend/test metainterp Message-ID: <20100304190853.78F5E282BD6@codespeak.net> Author: fijal Date: Thu Mar 4 20:08:51 2010 New Revision: 71736 Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/backend/test/test_random.py pypy/trunk/pypy/jit/metainterp/executor.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py Log: Freeze the CPU. Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Thu Mar 4 20:08:51 2010 @@ -14,11 +14,15 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr +class CPUMutableContainer(object): + _overflow_flag = False + class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): + self.mutable = CPUMutableContainer() assert type(opts) is not bool self.opts = opts @@ -50,12 +54,22 @@ self._setup_on_leave_jitted_translated() else: self._setup_on_leave_jitted_untranslated() + self.class_sizes = {} + + def set_overflow_flag(self, val): + self.mutable._overflow_flag = val + + def get_overflow_error(self): + return self.mutable._overflow_flag + + def _freeze_(self): + return True def setup(self): pass def set_class_sizes(self, class_sizes): - self.class_sizes = class_sizes + self.class_sizes.update(class_sizes) def _setup_prebuilt_error(self, prefix, Class): if self.rtyper is not None: # normal case @@ -105,8 +119,8 @@ v_i = _exception_emulator[1] _exception_emulator[0] = 0 _exception_emulator[1] = 0 - self.saved_exception = tp_i - self.saved_exc_value = self._cast_int_to_gcref(v_i) + self.mutable.saved_exception = tp_i + self.mutable.saved_exc_value = self._cast_int_to_gcref(v_i) self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -133,8 +147,8 @@ # from now on, the state is again consistent -- no more RPython # exception is set. The following code produces a write barrier # in the assignment to self.saved_exc_value, as needed. - self.saved_exception = exception - self.saved_exc_value = exc_value + self.mutable.saved_exception = exception + self.mutable.saved_exc_value = exc_value self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -172,14 +186,14 @@ return rffi.cast(lltype.Signed, f) def get_exception(self): - return self.saved_exception + return self.mutable.saved_exception def get_exc_value(self): - return self.saved_exc_value + return self.mutable.saved_exc_value def clear_exception(self): - self.saved_exception = 0 - self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.mutable.saved_exception = 0 + self.mutable.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) # ------------------- helpers and descriptions -------------------- Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Thu Mar 4 20:08:51 2010 @@ -8,6 +8,8 @@ portal_calldescr = None done_with_this_frame_int_v = -1 + _overflow_flag = False + def __init__(self): self.fail_descr_list = [] @@ -113,6 +115,12 @@ def get_zero_division_error(self): raise NotImplementedError + def get_overflow_flag(self): + return self._overflow_flag + + def set_overflow_flag(self, val): + self._overflow_flag = val + @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/trunk/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/test_random.py (original) +++ pypy/trunk/pypy/jit/backend/test/test_random.py Thu Mar 4 20:08:51 2010 @@ -264,8 +264,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu._overflow_flag: # overflow detected - del builder.cpu._overflow_flag + if builder.cpu.get_overflow_flag(): # overflow detected + builder.cpu.set_overflow_flag(False) op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including Modified: pypy/trunk/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/executor.py Thu Mar 4 20:08:51 2010 @@ -145,7 +145,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_sub_ovf(cpu, box1, box2): @@ -158,7 +158,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) def do_int_mul_ovf(cpu, box1, box2): @@ -171,7 +171,7 @@ z = 0 else: ovf = False - cpu._overflow_flag = ovf + cpu.set_overflow_flag(ovf) return BoxInt(z) # ---------- Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Thu Mar 4 20:08:51 2010 @@ -1898,8 +1898,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu._overflow_flag: - self.cpu._overflow_flag = False + if self.cpu.get_overflow_flag(): + self.cpu.set_overflow_flag(False) frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From fijal at codespeak.net Thu Mar 4 20:11:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:11:16 +0100 (CET) Subject: [pypy-svn] r71737 - in pypy/trunk/pypy/jit/backend: . llsupport Message-ID: <20100304191116.86DAA36C224@codespeak.net> Author: fijal Date: Thu Mar 4 20:11:15 2010 New Revision: 71737 Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/model.py Log: Move freezing of CPU up the class hierarchy Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Thu Mar 4 20:11:15 2010 @@ -62,9 +62,6 @@ def get_overflow_error(self): return self.mutable._overflow_flag - def _freeze_(self): - return True - def setup(self): pass Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Thu Mar 4 20:11:15 2010 @@ -13,6 +13,9 @@ def __init__(self): self.fail_descr_list = [] + def _freeze_(self): + return True + def get_fail_descr_number(self, descr): assert isinstance(descr, history.AbstractFailDescr) n = descr.index From fijal at codespeak.net Thu Mar 4 20:15:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:15:21 +0100 (CET) Subject: [pypy-svn] r71738 - pypy/branch/cleanup-warnings Message-ID: <20100304191521.0308636C224@codespeak.net> Author: fijal Date: Thu Mar 4 20:15:18 2010 New Revision: 71738 Removed: pypy/branch/cleanup-warnings/ Log: Kill the branch From fijal at codespeak.net Thu Mar 4 20:15:45 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:15:45 +0100 (CET) Subject: [pypy-svn] r71739 - pypy/branch/cleanup-warnings Message-ID: <20100304191545.1896C36C224@codespeak.net> Author: fijal Date: Thu Mar 4 20:15:42 2010 New Revision: 71739 Added: pypy/branch/cleanup-warnings/ - copied from r71738, pypy/trunk/ Log: Branch again - a branch to clen up warnings From fijal at codespeak.net Thu Mar 4 20:46:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:46:05 +0100 (CET) Subject: [pypy-svn] r71740 - pypy/branch/cleanup-warnings/pypy/jit/metainterp Message-ID: <20100304194605.A03B6282BD6@codespeak.net> Author: fijal Date: Thu Mar 4 20:46:03 2010 New Revision: 71740 Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py Log: Avoid annotator warnings, by adding abstract methods Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py Thu Mar 4 20:46:03 2010 @@ -125,6 +125,31 @@ def _clone_if_mutable(self): return self + def get_extra_info(self): + """ Implement in call descr + """ + raise NotImplementedError + + def is_array_of_pointers(self): + """ Implement for array descr + """ + raise NotImplementedError + + def is_array_of_floats(self): + """ Implement for array descr + """ + raise NotImplementedError + + def is_pointer_field(self): + """ Implement for field descr + """ + raise NotImplementedError + + def is_float_field(self): + """ Implement for field descr + """ + raise NotImplementedError + class AbstractFailDescr(AbstractDescr): index = -1 Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Thu Mar 4 20:46:03 2010 @@ -123,6 +123,21 @@ # meaning it has been forced. return self.box is None + def getfield(self, ofs, default): + raise NotImplementedError + + def setfield(self, ofs, value): + raise NotImplementedError + + def getitem(self, index): + raise NotImplementedError + + def getlength(self): + raise NotImplementedError + + def setitem(self, index, value): + raise NotImplementedError + class ConstantValue(OptValue): level = LEVEL_CONSTANT @@ -172,6 +187,8 @@ def _make_virtual(self, modifier): raise NotImplementedError("abstract base") + def _really_force(self): + raise NotImplementedError("abstract base") def get_fielddescrlist_cache(cpu): if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'): Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/resume.py Thu Mar 4 20:46:03 2010 @@ -397,6 +397,8 @@ def set_content(self, fieldnums): self.fieldnums = fieldnums + def debug_prints(self): + raise NotImplementedError class AbstractVirtualStructInfo(AbstractVirtualInfo): def __init__(self, fielddescrs): From fijal at codespeak.net Thu Mar 4 20:56:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 20:56:09 +0100 (CET) Subject: [pypy-svn] r71741 - in pypy/branch/cleanup-warnings/pypy/jit: backend/x86 metainterp Message-ID: <20100304195609.3B86F282BD6@codespeak.net> Author: fijal Date: Thu Mar 4 20:56:06 2010 New Revision: 71741 Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Log: Fight rtyper warnings Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/x86/assembler.py Thu Mar 4 20:56:06 2010 @@ -100,6 +100,7 @@ mc2 = None mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE _float_constants = None + _regalloc = None def __init__(self, cpu, translate_support_code=False, failargs_limit=1000): Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/x86/runner.py Thu Mar 4 20:56:06 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.objectmodel import we_are_translated -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile from pypy.jit.backend.x86.assembler import Assembler386 from pypy.jit.backend.x86.regalloc import FORCE_INDEX_OFS from pypy.jit.backend.x86.profagent import ProfileAgent @@ -141,3 +141,19 @@ import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(CPU) + +# silence warnings + +history.LoopToken._x86_param_depth = 0 +history.LoopToken._x86_arglocs = (None, None) +history.LoopToken._x86_frame_depth = 0 +history.LoopToken._x86_bootstrap_code = 0 +history.LoopToken._x86_direct_bootstrap_code = 0 +history.LoopToken._x86_failure_recovery_bytecode = 0 +history.LoopToken._x86_adr_jump_offset = 0 +history.LoopToken._x86_loop_code = 0 +history.LoopToken._x86_current_depths = (0, 0) + +compile._DoneWithThisFrameDescr._x86_current_depths = (0, 0) +compile._DoneWithThisFrameDescr._x86_failure_recovery_bytecode = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset = 0 Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/history.py Thu Mar 4 20:56:06 2010 @@ -710,6 +710,7 @@ terminating = False # see TerminatingLoopToken in compile.py # specnodes = ... # and more data specified by the backend when the loop is compiled + number = 0 def __init__(self, number=0): self.number = number @@ -889,6 +890,7 @@ compiled_count = 0 enter_count = 0 aborted_count = 0 + history = None def __init__(self): self.loops = [] Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/optimizeopt.py Thu Mar 4 20:56:06 2010 @@ -47,6 +47,7 @@ last_guard_index = -1 level = LEVEL_UNKNOWN + known_class = None def __init__(self, box): self.box = box From getxsick at codespeak.net Thu Mar 4 22:58:46 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 22:58:46 +0100 (CET) Subject: [pypy-svn] r71742 - in pypy/build/ubuntu/debian: . manpages scripts Message-ID: <20100304215846.89167282BD6@codespeak.net> Author: getxsick Date: Thu Mar 4 22:58:43 2010 New Revision: 71742 Added: pypy/build/ubuntu/debian/manpages/rpycompile.1 (props changed) - copied unchanged from r71721, pypy/build/ubuntu/debian/manpages/pypy-translate.1 pypy/build/ubuntu/debian/scripts/rpycompile (props changed) - copied unchanged from r71721, pypy/build/ubuntu/debian/scripts/pypy-translate Removed: pypy/build/ubuntu/debian/manpages/jscompile.1 pypy/build/ubuntu/debian/manpages/py.py.1 pypy/build/ubuntu/debian/manpages/pypy-translate.1 pypy/build/ubuntu/debian/pypy-dev.override pypy/build/ubuntu/debian/pypy-logic.install pypy/build/ubuntu/debian/scripts/jscompile pypy/build/ubuntu/debian/scripts/py.py pypy/build/ubuntu/debian/scripts/pypy-translate Modified: pypy/build/ubuntu/debian/changelog pypy/build/ubuntu/debian/pypy-dev.dirs pypy/build/ubuntu/debian/pypy-dev.install pypy/build/ubuntu/debian/pypy-dev.manpages pypy/build/ubuntu/debian/pypy.install pypy/build/ubuntu/debian/rules Log: update installation rules for 1.2 release remove outdated stuff rename pypy-translate script to rpycompile Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Thu Mar 4 22:58:43 2010 @@ -1,4 +1,4 @@ -pypy (1.2.0-svn71646-1) unstable; urgency=low +pypy (1.2.0-svn71721-1) unstable; urgency=low * New upstream release. * New maintainer. Modified: pypy/build/ubuntu/debian/pypy-dev.dirs ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.dirs (original) +++ pypy/build/ubuntu/debian/pypy-dev.dirs Thu Mar 4 22:58:43 2010 @@ -1,2 +1 @@ var/cache/pypy/_cache -usr/share/lintian/overrides Modified: pypy/build/ubuntu/debian/pypy-dev.install ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.install (original) +++ pypy/build/ubuntu/debian/pypy-dev.install Thu Mar 4 22:58:43 2010 @@ -4,7 +4,6 @@ pypy/__init__.py usr/share/pypy-1.2/pypy pypy/interpreter usr/share/pypy-1.2/pypy pypy/jit usr/share/pypy-1.2/pypy -pypy/lang usr/share/pypy-1.2/pypy pypy/module usr/share/pypy-1.2/pypy pypy/objspace usr/share/pypy-1.2/pypy pypy/rlib usr/share/pypy-1.2/pypy @@ -12,6 +11,4 @@ pypy/tool usr/share/pypy-1.2/pypy pypy/translator usr/share/pypy-1.2/pypy pypy/conftest.py usr/share/pypy-1.2/pypy -debian/scripts/py.py usr/bin -debian/scripts/pypy-translate usr/bin -debian/scripts/jscompile usr/bin +debian/scripts/rpycompile usr/bin Modified: pypy/build/ubuntu/debian/pypy-dev.manpages ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.manpages (original) +++ pypy/build/ubuntu/debian/pypy-dev.manpages Thu Mar 4 22:58:43 2010 @@ -1,3 +1 @@ -debian/manpages/py.py.1 -debian/manpages/pypy-translate.1 -debian/manpages/jscompile.1 +debian/manpages/rpycompile.1 Modified: pypy/build/ubuntu/debian/pypy.install ============================================================================== --- pypy/build/ubuntu/debian/pypy.install (original) +++ pypy/build/ubuntu/debian/pypy.install Thu Mar 4 22:58:43 2010 @@ -1 +1 @@ -debian/tmp/usr/bin/pypy usr/bin +bin/pypy usr/bin Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Thu Mar 4 22:58:43 2010 @@ -46,10 +46,9 @@ install-indep: dh_testdir dh_testroot - dh_clean -k -i + dh_prep -i dh_installdirs -i cp debian/pypy-lib.override debian/pypy-lib/usr/share/lintian/overrides/pypy-lib - cp debian/pypy-dev.override debian/pypy-dev/usr/share/lintian/overrides/pypy-dev dh_install -i find debian/pypy-lib -name "*.pyc" | xargs rm -rf find debian/pypy-dev -name "*.pyc" | xargs rm -rf @@ -58,7 +57,7 @@ install-arch: dh_testdir dh_testroot - dh_clean -k -s + dh_prep -s dh_installdirs -s $(MAKE) install dh_install -s From fijal at codespeak.net Thu Mar 4 23:00:41 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 23:00:41 +0100 (CET) Subject: [pypy-svn] r71743 - in pypy/trunk/pypy/rlib: . test Message-ID: <20100304220041.9A5C0282BD7@codespeak.net> Author: fijal Date: Thu Mar 4 23:00:39 2010 New Revision: 71743 Modified: pypy/trunk/pypy/rlib/test/test_timer.py pypy/trunk/pypy/rlib/timer.py Log: A new interface, to avoid concatenation of strings in case we don't actually use timer. Modified: pypy/trunk/pypy/rlib/test/test_timer.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_timer.py (original) +++ pypy/trunk/pypy/rlib/test/test_timer.py Thu Mar 4 23:00:39 2010 @@ -15,6 +15,8 @@ t.start("testb") t.stop("testb") t.stop("testb") + t.start_name("test", "one") + t.stop_name("test", "one") t.dump() Modified: pypy/trunk/pypy/rlib/timer.py ============================================================================== --- pypy/trunk/pypy/rlib/timer.py (original) +++ pypy/trunk/pypy/rlib/timer.py Thu Mar 4 23:00:39 2010 @@ -30,6 +30,9 @@ self.timings[name] = time.time() - self.timings.get(name, 0) self.levels[timer] = new_level + def start_name(self, timerone, timertwo): + self.start(timerone + " " + timertwo) + def stop(self, timer): level = self.levels.setdefault(timer, -1) if level == -1: @@ -39,6 +42,9 @@ self.timings[name] = time.time() - self.timings[name] self.levels[timer] = level - 1 + def stop_name(self, timerone, timertwo): + self.stop(timerone + " " + timertwo) + def value(self, timer): level = self.levels.get(timer, -1) if level == -1: @@ -58,8 +64,12 @@ class DummyTimer: def start(self, timer): pass + def start_name(self, timerone, timertwo): + pass def stop(self, timer): pass + def stop_name(self, timerone, timertwo): + pass def value(self, timer): return "Timing disabled" def dump(self): From fijal at codespeak.net Thu Mar 4 23:03:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 4 Mar 2010 23:03:25 +0100 (CET) Subject: [pypy-svn] r71744 - pypy/trunk/pypy/module/imp Message-ID: <20100304220325.92147282BD8@codespeak.net> Author: fijal Date: Thu Mar 4 23:03:23 2010 New Revision: 71744 Modified: pypy/trunk/pypy/module/imp/importing.py Log: Avoid string concatenation here. It's a bit of microoptimization, true, but also painless Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Thu Mar 4 23:03:23 2010 @@ -82,8 +82,7 @@ def importhook(space, modulename, w_globals=None, w_locals=None, w_fromlist=None, level=-1): - timername = "importhook " + modulename - space.timer.start(timername) + space.timer.start_name("importhook", modulename) if not modulename and level < 0: raise OperationError( space.w_ValueError, @@ -131,7 +130,7 @@ baselevel, w_fromlist, tentative=1) if w_mod is not None: - space.timer.stop(timername) + space.timer.stop_name("importhook", modulename) return w_mod else: rel_modulename = None @@ -141,7 +140,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) + space.timer.stop_name("importhook", modulename) return w_mod # importhook.unwrap_spec = [ObjSpace, str, W_Root, W_Root, W_Root, int] From getxsick at codespeak.net Thu Mar 4 23:33:57 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 23:33:57 +0100 (CET) Subject: [pypy-svn] r71745 - pypy/build/ubuntu/debian Message-ID: <20100304223357.925E651057@codespeak.net> Author: getxsick Date: Thu Mar 4 23:33:56 2010 New Revision: 71745 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/rules Log: remove unnecessary symlinks Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Thu Mar 4 23:33:56 2010 @@ -4,7 +4,6 @@ TRANSLATEOPTS=--batch --source -Ojit TARGETOPTS=%(TARGETOPTS)s PREFIX=%(PREFIX)s -OUTPUTDIR=debian/tmp/usr/bin LOGIC=-o logic BINARIES=%(BINARIES)s @@ -35,6 +34,7 @@ --resultlog=pypyjit.log \ pypy/module/pypyjit/test || true; \ echo "Finished testing JIT"; + @rm -f $(CURDIR)/pypy/translator/goal/pypy-c .NOTPARALLEL: $(BINARIES) Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Thu Mar 4 23:33:56 2010 @@ -52,7 +52,8 @@ dh_install -i find debian/pypy-lib -name "*.pyc" | xargs rm -rf find debian/pypy-dev -name "*.pyc" | xargs rm -rf - rm debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE + rm -f debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE + rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py install-arch: dh_testdir From getxsick at codespeak.net Thu Mar 4 23:40:39 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 23:40:39 +0100 (CET) Subject: [pypy-svn] r71746 - pypy/build/ubuntu/debian Message-ID: <20100304224039.1FDED51055@codespeak.net> Author: getxsick Date: Thu Mar 4 23:40:37 2010 New Revision: 71746 Modified: pypy/build/ubuntu/debian/control Log: update package dependence and switch architecture of pypy package to i386 Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Thu Mar 4 23:40:37 2010 @@ -10,8 +10,8 @@ Package: pypy-dev Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, python-codespeak-lib (>= 0.9.0), pypy-lib (>= ${source:Version}), python, python-ctypes -Recommends: pypy-doc, python-pygame, graphviz, python-dev, gcc, libgc-dev, llvm-cfe, mono-gmcs, spidermonkey-bin, jasmin-sable, libreadline5-dev +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib (>= ${source:Version}), python, python-ctypes, gcc, libffi-dev, zlib1g-dev, libbz2-dev +Recommends: pypy-doc, python-dev, libgc-dev, llvm-cfe, mono-gmcs, spidermonkey-bin, jasmin-sable, libreadline5-dev Suggests: gcl-dev Description: the Python in python interpreter, interpreted version The PyPy project aims to provide a Python implementation of the Python @@ -26,8 +26,8 @@ build a custom translated version of the PyPy interpreter. Package: pypy -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib +Architecture: i386 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, libffi, zlib1g, libbz2-dev Description: the Python in Python interpreter, C backend translation The PyPy project aims to provide a Python implementation of the Python interpreter. From getxsick at codespeak.net Thu Mar 4 23:58:38 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 4 Mar 2010 23:58:38 +0100 (CET) Subject: [pypy-svn] r71747 - pypy/build/ubuntu/debian/manpages Message-ID: <20100304225838.E70A5282BD8@codespeak.net> Author: getxsick Date: Thu Mar 4 23:58:37 2010 New Revision: 71747 Modified: pypy/build/ubuntu/debian/manpages/pypy.1 pypy/build/ubuntu/debian/manpages/rpycompile.1 Log: update manual pages Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Thu Mar 4 23:58:37 2010 @@ -1,4 +1,4 @@ -.TH PYPY 1 "January 27, 2008" +.TH PYPY 1 "March 4, 2010" .SH NAME pypy \- PyPy Python interpreter compiled using the C backend. .SH SYNOPSIS @@ -35,12 +35,10 @@ .B \-\-info Print translation information about this PyPy executable. .SH SEE ALSO -.BR pypy-stackless (1), -.BR py.py (1), -.BR pypy-translate (1), -.BR jscompile (1) +.BR rpycompile (1), .SH AUTHORS -\fBPyPy\fP was written by the members of the PyPy project . +\fBPyPy\fP was written by the members of the PyPy project . .PP -This manual page was written by Chris Lamb , +This manual page was updated by Bartosz Skowron . +The manual page was originally written by Chris Lamb , for the Debian project (but may be used by others). Modified: pypy/build/ubuntu/debian/manpages/rpycompile.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/rpycompile.1 (original) +++ pypy/build/ubuntu/debian/manpages/rpycompile.1 Thu Mar 4 23:58:37 2010 @@ -1,21 +1,19 @@ -.TH PYPY-TRANSLATE 1 "January 27, 2008" +.TH RPYCOMPILE 1 "March 4, 2010" .SH NAME -pypy-translate \- PyPy translation tool. +rpycompile \- PyPy translation tool. .SH SYNOPSIS -.B pypy-translate +.B rpycompile .RI [options] .SH OPTIONS -\fBpypy-translate\fP has a very large number of options which are changing +\fBrpycompile\fP has a very large number of options which are changing often. .TP -To see the full list, please see the documentation. +To see the full list, please see the documentation or \fB--help\fP option. .SH SEE ALSO .BR pypy (1), -.BR pypy-stackless (1), -.BR py.py (1), -.BR jscompile (1) .SH AUTHORS -\fBPyPy\fP was written by the members of the PyPy project . +\fBPyPy\fP was written by the members of the PyPy project . .PP -This manual page was written by Chris Lamb , +This manual page was updated by Bartosz Skowron . +The manual page was originally written by Chris Lamb , for the Debian project (but may be used by others). From benjamin at codespeak.net Fri Mar 5 00:27:47 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 00:27:47 +0100 (CET) Subject: [pypy-svn] r71748 - pypy/branch/import-fiddle Message-ID: <20100304232747.DBA1851057@codespeak.net> Author: benjamin Date: Fri Mar 5 00:27:46 2010 New Revision: 71748 Added: pypy/branch/import-fiddle/ - copied from r71747, pypy/trunk/ Log: make a branch for hacking import a little From benjamin at codespeak.net Fri Mar 5 00:29:04 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 00:29:04 +0100 (CET) Subject: [pypy-svn] r71749 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100304232904.A980C51059@codespeak.net> Author: benjamin Date: Fri Mar 5 00:29:02 2010 New Revision: 71749 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: don't examine globals if it's not needed Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 00:29:02 2010 @@ -89,8 +89,10 @@ space.wrap("Empty module name")) w = space.wrap - ctxt_name = None - if w_globals is not None and not space.is_w(w_globals, space.w_None): + rel_modulename = None + if (level != 0 and + w_globals is not None and + not space.is_w(w_globals, space.w_None)): ctxt_w_name = space.finditem(w_globals, w('__name__')) ctxt_w_path = space.finditem(w_globals, w('__path__')) if ctxt_w_name is not None: @@ -99,41 +101,31 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - else: - ctxt_w_path = None - - rel_modulename = None - if ctxt_name is not None: - if level == 0: - baselevel = 0 - rel_modulename = modulename - else: - ctxt_name_prefix_parts = ctxt_name.split('.') - if level > 0: - n = len(ctxt_name_prefix_parts)-level+1 - assert n>=0 - ctxt_name_prefix_parts = ctxt_name_prefix_parts[:n] - if ctxt_w_path is None: # plain module - ctxt_name_prefix_parts.pop() - if ctxt_name_prefix_parts: - rel_modulename = '.'.join(ctxt_name_prefix_parts) - if modulename: - rel_modulename += '.' + modulename - baselevel = len(ctxt_name_prefix_parts) - - if rel_modulename is not None: - w_mod = check_sys_modules(space, w(rel_modulename)) - if (w_mod is None or - not space.is_w(w_mod, space.w_None)): - - w_mod = absolute_import(space, rel_modulename, - baselevel, - w_fromlist, tentative=1) - if w_mod is not None: - space.timer.stop_name("importhook", modulename) - return w_mod else: - rel_modulename = None + ctxt_name_prefix_parts = ctxt_name.split('.') + if level > 0: + n = len(ctxt_name_prefix_parts)-level+1 + assert n>=0 + ctxt_name_prefix_parts = ctxt_name_prefix_parts[:n] + if ctxt_w_path is None: # plain module + ctxt_name_prefix_parts.pop() + if ctxt_name_prefix_parts: + rel_modulename = '.'.join(ctxt_name_prefix_parts) + if modulename: + rel_modulename += '.' + modulename + baselevel = len(ctxt_name_prefix_parts) + if rel_modulename is not None: + w_mod = check_sys_modules(space, w(rel_modulename)) + if (w_mod is None or + not space.is_w(w_mod, space.w_None)): + w_mod = absolute_import(space, rel_modulename, + baselevel, + w_fromlist, tentative=1) + if w_mod is not None: + space.timer.stop_name("importhook", modulename) + return w_mod + else: + rel_modulename = None if level > 0: msg = "Attempted relative import in non-package" raise OperationError(space.w_ValueError, w(msg)) From benjamin at codespeak.net Fri Mar 5 00:37:05 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 00:37:05 +0100 (CET) Subject: [pypy-svn] r71750 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100304233705.38BA951059@codespeak.net> Author: benjamin Date: Fri Mar 5 00:37:03 2010 New Revision: 71750 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: space Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 00:37:03 2010 @@ -131,7 +131,7 @@ raise OperationError(space.w_ValueError, w(msg)) 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.setitem(space.sys.get('modules'), w(rel_modulename), space.w_None) space.timer.stop_name("importhook", modulename) return w_mod # From fijal at codespeak.net Fri Mar 5 00:45:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 00:45:35 +0100 (CET) Subject: [pypy-svn] r71751 - pypy/branch/string-promote Message-ID: <20100304234535.A909B51059@codespeak.net> Author: fijal Date: Fri Mar 5 00:45:34 2010 New Revision: 71751 Removed: pypy/branch/string-promote/ Log: Remove merged branch From fijal at codespeak.net Fri Mar 5 00:48:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 00:48:09 +0100 (CET) Subject: [pypy-svn] r71752 - pypy/branch/parser-playground Message-ID: <20100304234809.70B755105A@codespeak.net> Author: fijal Date: Fri Mar 5 00:48:07 2010 New Revision: 71752 Removed: pypy/branch/parser-playground/ Log: Kill this branch, it's horribly outdated if nothing else - if you need it cfbolz, please revive From fijal at codespeak.net Fri Mar 5 00:49:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 00:49:02 +0100 (CET) Subject: [pypy-svn] r71753 - pypy/branch/js-refactoring Message-ID: <20100304234902.211075105B@codespeak.net> Author: fijal Date: Fri Mar 5 00:49:00 2010 New Revision: 71753 Removed: pypy/branch/js-refactoring/ Log: This branch was merged to lang From fijal at codespeak.net Fri Mar 5 00:50:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 00:50:20 +0100 (CET) Subject: [pypy-svn] r71754 - pypy/branch/gcremovetypeptr Message-ID: <20100304235020.7EF1D5105C@codespeak.net> Author: fijal Date: Fri Mar 5 00:50:18 2010 New Revision: 71754 Removed: pypy/branch/gcremovetypeptr/ Log: This branch was only for running performance plots, I think it's done From fijal at codespeak.net Fri Mar 5 00:51:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 00:51:06 +0100 (CET) Subject: [pypy-svn] r71755 - pypy/branch/asmgcc-cantcollect Message-ID: <20100304235106.3097C5105D@codespeak.net> Author: fijal Date: Fri Mar 5 00:51:04 2010 New Revision: 71755 Removed: pypy/branch/asmgcc-cantcollect/ Log: Kill merged branch From getxsick at codespeak.net Fri Mar 5 02:24:01 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 02:24:01 +0100 (CET) Subject: [pypy-svn] r71756 - pypy/build/ubuntu/debian Message-ID: <20100305012401.C1E955105E@codespeak.net> Author: getxsick Date: Fri Mar 5 02:24:00 2010 New Revision: 71756 Modified: pypy/build/ubuntu/debian/changelog pypy/build/ubuntu/debian/control pypy/build/ubuntu/debian/rules Log: fix warnings noticed by lintian Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Fri Mar 5 02:24:00 2010 @@ -1,7 +1,10 @@ -pypy (1.2.0-svn71721-1) unstable; urgency=low +pypy (1.2.0-1) unstable; urgency=low * New upstream release. * New maintainer. + * Only JIT-oriented upstream (e.g. stackless is dropped) + * Rename pypy-translate to rpycompile + * Run tests (-A, lib-python, JIT) * Switch to dpkg-source 3.0 (native) format -- Bartosz Skowron Tue, 02 Mar 2010 18:08:37 +0100 Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 5 02:24:00 2010 @@ -1,12 +1,10 @@ Source: pypy Section: python Priority: extra -Maintainer: Chris Lamb -Build-Depends: debhelper (>= 6), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev -Standards-Version: 3.7.3 -Vcs-Git: git://git.chris-lamb.co.uk/pkg-pypy.git -Vcs-Browser: http://git.chris-lamb.co.uk/?p=pkg-pypy.git -Homepage: http://codespeak.net/pypy/ +Maintainer: Bartosz Skowron +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev +Standards-Version: 3.8.0 +Homepage: http://pypy.org Package: pypy-dev Architecture: all Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Fri Mar 5 02:24:00 2010 @@ -54,6 +54,8 @@ find debian/pypy-dev -name "*.pyc" | xargs rm -rf rm -f debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py + rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o + rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ install-arch: dh_testdir From fijal at codespeak.net Fri Mar 5 02:43:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 02:43:53 +0100 (CET) Subject: [pypy-svn] r71757 - pypy/branch/import-fiddle/pypy/module/pypyjit Message-ID: <20100305014353.586965105E@codespeak.net> Author: fijal Date: Fri Mar 5 02:43:29 2010 New Revision: 71757 Modified: pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py Log: Look into those modules Modified: pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py (original) +++ pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py Fri Mar 5 02:43:29 2010 @@ -11,7 +11,8 @@ if '.' in modname: modname, _ = modname.split('.', 1) - if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions']: + if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', + 'sys', 'imp']: return True return False From fijal at codespeak.net Fri Mar 5 02:59:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 02:59:05 +0100 (CET) Subject: [pypy-svn] r71758 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305015905.B8F0C282BD9@codespeak.net> Author: fijal Date: Fri Mar 5 02:58:54 2010 New Revision: 71758 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: Fight fight fight. Fastpath for *something* Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 02:58:54 2010 @@ -9,7 +9,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.eval import Code -from pypy.rlib import streamio +from pypy.rlib import streamio, jit from pypy.rlib.streamio import StreamErrors from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import we_are_translated @@ -80,6 +80,9 @@ def check_sys_modules(space, w_modulename): return space.finditem(space.sys.get('modules'), w_modulename) +def check_sys_modules_w(space, modulename): + return space.finditem_str(space.sys.get('modules'), modulename) + def importhook(space, modulename, w_globals=None, w_locals=None, w_fromlist=None, level=-1): space.timer.start_name("importhook", modulename) @@ -89,6 +92,11 @@ space.wrap("Empty module name")) w = space.wrap + if w_fromlist is not None and space.is_true(w_fromlist): + fromlist_w = space.fixedview(w_fromlist) + else: + fromlist_w = None + rel_modulename = None if (level != 0 and w_globals is not None and @@ -120,7 +128,7 @@ not space.is_w(w_mod, space.w_None)): w_mod = absolute_import(space, rel_modulename, baselevel, - w_fromlist, tentative=1) + fromlist_w, tentative=1) if w_mod is not None: space.timer.stop_name("importhook", modulename) return w_mod @@ -129,7 +137,9 @@ if level > 0: msg = "Attempted relative import in non-package" raise OperationError(space.w_ValueError, w(msg)) - w_mod = absolute_import(space, modulename, 0, w_fromlist, tentative=0) + w_mod = absolute_import_try(space, modulename, 0, fromlist_w) + if w_mod is None and not space.is_w(w_mod, space.w_None): + w_mod = absolute_import(space, modulename, 0, fromlist_w, tentative=0) if rel_modulename is not None: space.setitem(space.sys.get('modules'), w(rel_modulename), space.w_None) space.timer.stop_name("importhook", modulename) @@ -137,16 +147,27 @@ # importhook.unwrap_spec = [ObjSpace, str, W_Root, W_Root, W_Root, int] -def absolute_import(space, modulename, baselevel, w_fromlist, tentative): +def absolute_import(space, modulename, baselevel, fromlist_w, tentative): lock = getimportlock(space) lock.acquire_lock() try: return _absolute_import(space, modulename, baselevel, - w_fromlist, tentative) + fromlist_w, tentative) finally: lock.release_lock() -def _absolute_import(space, modulename, baselevel, w_fromlist, tentative): + at jit.unroll_safe +def absolute_import_try(space, modulename, baselevel, fromlist_w): + """ Only look up sys.modules, not actually try to load anything + """ + last_dot = 0 + if '.' not in modulename: + w_mod = check_sys_modules_w(space, modulename) + if fromlist_w is not None: + return None + return None + +def _absolute_import(space, modulename, baselevel, fromlist_w, tentative): w = space.wrap w_mod = None @@ -170,13 +191,12 @@ w_path = try_getattr(space, w_mod, w('__path__')) level += 1 - if w_fromlist is not None and space.is_true(w_fromlist): + if fromlist_w is not None: if w_path is not None: - fromlist_w = space.unpackiterable(w_fromlist) if len(fromlist_w) == 1 and space.eq_w(fromlist_w[0],w('*')): w_all = try_getattr(space, w_mod, w('__all__')) if w_all is not None: - fromlist_w = space.unpackiterable(w_all) + fromlist_w = space.fixedview(w_all) for w_name in fromlist_w: if try_getattr(space, w_mod, w_name) is None: load_part(space, w_path, prefix, space.str_w(w_name), w_mod, From fijal at codespeak.net Fri Mar 5 03:26:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 03:26:33 +0100 (CET) Subject: [pypy-svn] r71759 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305022633.72200282BD6@codespeak.net> Author: fijal Date: Fri Mar 5 03:26:31 2010 New Revision: 71759 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: an attempt to have jit-friendly fast-path for stuff that has it's place in sys.modules Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 03:26:31 2010 @@ -160,12 +160,41 @@ def absolute_import_try(space, modulename, baselevel, fromlist_w): """ Only look up sys.modules, not actually try to load anything """ + w_path = None last_dot = 0 if '.' not in modulename: w_mod = check_sys_modules_w(space, modulename) - if fromlist_w is not None: - return None - return None + first = w_mod + if fromlist_w is not None and w_mod is not None: + w_path = try_getattr(space, w_mod, space.wrap('__path__')) + else: + level = 0 + first = None + while last_dot != -1: + last_dot = modulename.find('.', last_dot + 1) + if last_dot == -1: + w_mod = check_sys_modules_w(space, modulename) + else: + w_mod = check_sys_modules_w(space, modulename[:last_dot]) + if w_mod is None or space.is_w(w_mod, space.w_None): + return None + if level == baselevel: + first = w_mod + if fromlist_w is not None: + w_path = try_getattr(space, w_mod, space.wrap('__path__')) + level += 1 + if fromlist_w is not None: + if w_path is not None: + if len(fromlist_w) == 1 and space.eq_w(fromlist_w[0], + space.wrap('*')): + w_all = try_getattr(space, w_mod, space.wrap('__all__')) + if w_all is not None: + fromlist_w = space.fixedview(w_all) + for w_name in fromlist_w: + if try_getattr(space, w_mod, w_name) is None: + return None + return w_mod + return first def _absolute_import(space, modulename, baselevel, fromlist_w, tentative): w = space.wrap @@ -188,7 +217,8 @@ first = w_mod tentative = 0 prefix.append(part) - w_path = try_getattr(space, w_mod, w('__path__')) + if fromlist_w is not None: + w_path = try_getattr(space, w_mod, w('__path__')) level += 1 if fromlist_w is not None: From fijal at codespeak.net Fri Mar 5 03:32:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 03:32:04 +0100 (CET) Subject: [pypy-svn] r71760 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305023204.59E23282BD7@codespeak.net> Author: fijal Date: Fri Mar 5 03:31:59 2010 New Revision: 71760 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: fix translation Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 03:31:59 2010 @@ -175,6 +175,7 @@ if last_dot == -1: w_mod = check_sys_modules_w(space, modulename) else: + assert last_dot >= 0 w_mod = check_sys_modules_w(space, modulename[:last_dot]) if w_mod is None or space.is_w(w_mod, space.w_None): return None From fijal at codespeak.net Fri Mar 5 03:46:32 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 03:46:32 +0100 (CET) Subject: [pypy-svn] r71761 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305024632.47219282BD8@codespeak.net> Author: fijal Date: Fri Mar 5 03:46:29 2010 New Revision: 71761 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: fix rtyping Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 03:46:29 2010 @@ -171,6 +171,7 @@ level = 0 first = None while last_dot != -1: + assert last_dot >= 0 # bah last_dot = modulename.find('.', last_dot + 1) if last_dot == -1: w_mod = check_sys_modules_w(space, modulename) From fijal at codespeak.net Fri Mar 5 04:07:27 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 04:07:27 +0100 (CET) Subject: [pypy-svn] r71762 - pypy/branch/import-fiddle/pypy/module/sys Message-ID: <20100305030727.39121282BD8@codespeak.net> Author: fijal Date: Fri Mar 5 04:07:24 2010 New Revision: 71762 Modified: pypy/branch/import-fiddle/pypy/module/sys/state.py Log: (cfbolz) Use celldict for sys.modules (this it the *actual* optimization) Modified: pypy/branch/import-fiddle/pypy/module/sys/state.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/sys/state.py (original) +++ pypy/branch/import-fiddle/pypy/module/sys/state.py Fri Mar 5 04:07:24 2010 @@ -14,7 +14,7 @@ def __init__(self, space): self.space = space - self.w_modules = space.newdict() + self.w_modules = space.newdict(module=True) self.w_warnoptions = space.newlist([]) self.w_argv = space.newlist([]) From getxsick at codespeak.net Fri Mar 5 04:15:02 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:15:02 +0100 (CET) Subject: [pypy-svn] r71763 - pypy/build/ubuntu/debian Message-ID: <20100305031502.C3194282BD8@codespeak.net> Author: getxsick Date: Fri Mar 5 04:14:58 2010 New Revision: 71763 Modified: pypy/build/ubuntu/debian/pypy-dev.install Log: add testrunner, greenlet and pylib to pypy-dev Modified: pypy/build/ubuntu/debian/pypy-dev.install ============================================================================== --- pypy/build/ubuntu/debian/pypy-dev.install (original) +++ pypy/build/ubuntu/debian/pypy-dev.install Fri Mar 5 04:14:58 2010 @@ -11,4 +11,7 @@ pypy/tool usr/share/pypy-1.2/pypy pypy/translator usr/share/pypy-1.2/pypy pypy/conftest.py usr/share/pypy-1.2/pypy +py usr/share/pypy-1.2 +greenlet usr/share/pypy-1.2 +testrunner usr/share/pypy-1.2 debian/scripts/rpycompile usr/bin From getxsick at codespeak.net Fri Mar 5 04:15:50 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:15:50 +0100 (CET) Subject: [pypy-svn] r71764 - pypy/build/ubuntu/debian Message-ID: <20100305031550.D5F7F282BD9@codespeak.net> Author: getxsick Date: Fri Mar 5 04:15:48 2010 New Revision: 71764 Modified: pypy/build/ubuntu/debian/pypy-doc.docs Log: add README to pypy-doc Modified: pypy/build/ubuntu/debian/pypy-doc.docs ============================================================================== --- pypy/build/ubuntu/debian/pypy-doc.docs (original) +++ pypy/build/ubuntu/debian/pypy-doc.docs Fri Mar 5 04:15:48 2010 @@ -1 +1,2 @@ pypy/doc/* +README From getxsick at codespeak.net Fri Mar 5 04:17:27 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:17:27 +0100 (CET) Subject: [pypy-svn] r71765 - pypy/build/ubuntu/debian Message-ID: <20100305031727.C2027282BDA@codespeak.net> Author: getxsick Date: Fri Mar 5 04:17:25 2010 New Revision: 71765 Modified: pypy/build/ubuntu/debian/rules Log: make hard copy of ctypes_configure to pypy/lib/ instead of symlink Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Fri Mar 5 04:17:25 2010 @@ -56,6 +56,8 @@ rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ + rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/ctypes_configure + cp -r ctypes_configure debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/ install-arch: dh_testdir From benjamin at codespeak.net Fri Mar 5 04:20:53 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 04:20:53 +0100 (CET) Subject: [pypy-svn] r71766 - in pypy/branch/import-fiddle/lib-python/2.5.2: . lib-tk plat-irix5 plat-mac/Carbon plat-sunos5 test Message-ID: <20100305032053.06D66282BD9@codespeak.net> Author: benjamin Date: Fri Mar 5 04:20:50 2010 New Revision: 71766 Modified: pypy/branch/import-fiddle/lib-python/2.5.2/lib-tk/Tix.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/AL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CD.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CL_old.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/DEVICE.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/ERRNO.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/FILE.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/FL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GET.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GLWS.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/IN.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/IOCTL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/SV.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/WAIT.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/cddb.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/cdplayer.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/flp.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/jpeg.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/panel.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/panelparser.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/readcd.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/torgb.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CG.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-sunos5/IN.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/runpy.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_aepack.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_binascii.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_grp.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_htmlparser.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_wsgiref.py (props changed) Log: remove svn:executable property from files that do not have a shebang line From benjamin at codespeak.net Fri Mar 5 04:22:42 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 04:22:42 +0100 (CET) Subject: [pypy-svn] r71767 - in pypy/branch/import-fiddle/lib-python/2.5.2: . lib-tk plat-irix5 plat-mac/Carbon plat-sunos5 test Message-ID: <20100305032242.23BD4282BD9@codespeak.net> Author: benjamin Date: Fri Mar 5 04:22:39 2010 New Revision: 71767 Modified: pypy/branch/import-fiddle/lib-python/2.5.2/lib-tk/Tix.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/AL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CD.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/CL_old.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/DEVICE.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/ERRNO.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/FILE.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/FL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GET.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/GLWS.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/IN.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/IOCTL.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/SV.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/WAIT.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/cddb.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/cdplayer.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/flp.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/jpeg.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/panel.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/panelparser.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/readcd.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-irix5/torgb.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CG.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-sunos5/IN.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/runpy.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_aepack.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_binascii.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_grp.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_htmlparser.py (props changed) pypy/branch/import-fiddle/lib-python/2.5.2/test/test_wsgiref.py (props changed) Log: revert change unintended for this branch From getxsick at codespeak.net Fri Mar 5 04:23:43 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:23:43 +0100 (CET) Subject: [pypy-svn] r71768 - in pypy/trunk: . pypy/doc Message-ID: <20100305032343.534A8282BD9@codespeak.net> Author: getxsick Date: Fri Mar 5 04:23:41 2010 New Revision: 71768 Modified: pypy/trunk/LICENSE pypy/trunk/pypy/doc/contributor.txt Log: capitalize my name Modified: pypy/trunk/LICENSE ============================================================================== --- pypy/trunk/LICENSE (original) +++ pypy/trunk/LICENSE Fri Mar 5 04:23:41 2010 @@ -85,7 +85,7 @@ Lukas Renggli Guenter Jantzen Dinu Gherman - Bartosz SKOWRON + Bartosz Skowron Georg Brandl Ben Young Jean-Paul Calderone Modified: pypy/trunk/pypy/doc/contributor.txt ============================================================================== --- pypy/trunk/pypy/doc/contributor.txt (original) +++ pypy/trunk/pypy/doc/contributor.txt Fri Mar 5 04:23:41 2010 @@ -58,7 +58,7 @@ Lukas Renggli Guenter Jantzen Dinu Gherman - Bartosz SKOWRON + Bartosz Skowron Georg Brandl Ben Young Jean-Paul Calderone From benjamin at codespeak.net Fri Mar 5 04:23:52 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 5 Mar 2010 04:23:52 +0100 (CET) Subject: [pypy-svn] r71769 - in pypy/trunk/lib-python/2.5.2: . lib-tk plat-irix5 plat-mac/Carbon plat-sunos5 test Message-ID: <20100305032352.516ED282BD9@codespeak.net> Author: benjamin Date: Fri Mar 5 04:23:49 2010 New Revision: 71769 Modified: pypy/trunk/lib-python/2.5.2/lib-tk/Tix.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/AL.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/CD.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/CL.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/CL_old.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/DEVICE.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/ERRNO.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/FILE.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/FL.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/GET.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/GL.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/GLWS.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/IN.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/IOCTL.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/SV.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/WAIT.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/cddb.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/cdplayer.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/flp.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/jpeg.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/panel.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/panelparser.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/readcd.py (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/torgb.py (props changed) pypy/trunk/lib-python/2.5.2/plat-mac/Carbon/CG.py (props changed) pypy/trunk/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py (props changed) pypy/trunk/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py (props changed) pypy/trunk/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py (props changed) pypy/trunk/lib-python/2.5.2/plat-sunos5/IN.py (props changed) pypy/trunk/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py (props changed) pypy/trunk/lib-python/2.5.2/runpy.py (props changed) pypy/trunk/lib-python/2.5.2/test/test_aepack.py (props changed) pypy/trunk/lib-python/2.5.2/test/test_binascii.py (props changed) pypy/trunk/lib-python/2.5.2/test/test_grp.py (props changed) pypy/trunk/lib-python/2.5.2/test/test_htmlparser.py (props changed) pypy/trunk/lib-python/2.5.2/test/test_wsgiref.py (props changed) Log: remove svn:executable property from files that don't have a shebang line From getxsick at codespeak.net Fri Mar 5 04:30:52 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:30:52 +0100 (CET) Subject: [pypy-svn] r71770 - pypy/build/ubuntu/debian Message-ID: <20100305033052.AF999282BD7@codespeak.net> Author: getxsick Date: Fri Mar 5 04:30:51 2010 New Revision: 71770 Modified: pypy/build/ubuntu/debian/copyright Log: update copyright Modified: pypy/build/ubuntu/debian/copyright ============================================================================== --- pypy/build/ubuntu/debian/copyright (original) +++ pypy/build/ubuntu/debian/copyright Fri Mar 5 04:30:51 2010 @@ -1,127 +1,185 @@ -This package was debianized by Alexandre Fayolle on -Mon, 8 Jan 2007 19:13:59 +0100. +This package was debianized by Bartosz Skowron on +Fri, 05 Mar 2010 04:18:53 +0100. -It was downloaded from . +It was downloaded from . Upstream Authors: Armin Rigo + Maciej Fijalkowski + Carl Friedrich Bolz Samuele Pedroni + Antonio Cuni Michael Hudson - Carl Friedrich Bolz Christian Tismer Holger Krekel Eric van Riet Paap - Antonio Cuni - Anders Chrigstrom - Maciek Fijalkowski Richard Emslie + Anders Chrigstrom + Amaury Forgeot d Arc Aurelien Campeas Anders Lehmann Niklaus Haldimann Seo Sanghyeon + Leonardo Santagada Lawrence Oluyede - Alex Martelli + Jakub Gustak + Guido Wesdorp + Benjamin Peterson + Alexander Schremmer + Niko Matsakis Ludovic Aubry - Adrien Di Mascio + Alex Martelli + Toon Verwaest Stephan Diehl - Guido Wesdorp + Adrien Di Mascio Stefan Schwarzer Tomek Meka Patrick Maupin - Leonardo Santagada - Bob Ippolito - Laura Creighton Jacob Hallen + Laura Creighton + Bob Ippolito + Camillo Bruni + Simon Burton + Bruno Gola + Alexandre Fayolle Marius Gedminas - Niko Matsakis - Amaury Forgeot d Arc Guido van Rossum Valentino Volonghi - Alexander Schremmer - Alexandre Fayolle - Wanja Saatkamp + Adrian Kuhn + Paul deGrandis Gerald Klix + Wanja Saatkamp + Anders Hammarquist + Oscar Nierstrasz Eugene Oden - Dinu Gherman + Lukas Renggli Guenter Jantzen + Dinu Gherman + Bartosz Skowron + Georg Brandl Ben Young + Jean-Paul Calderone Nicolas Chauvat - Michael Twomey Rocco Moretti - Simon Burton - Boris Feigin + Michael Twomey + boria + Jared Grubb Olivier Dormond - Gintautas Miliauskas Stuart Williams Jens-Uwe Mager + Justas Sadzevicius + Mikael Sch?nenberg Brian Dorsey Jonathan David Riehl - Anders Qvist Beatrice During + Elmo M?ntynen Andreas Friedge + Alex Gaynor + Anders Qvist Alan McIntyre Bert Freudenberg - Heinrich-Heine University, Germany + Heinrich-Heine University, Germany Open End AB (formerly AB Strakt), Sweden - merlinux GmbH, Germany - tismerysoft GmbH, Germany - Logilab Paris, France - DFKI GmbH, Germany + merlinux GmbH, Germany + tismerysoft GmbH, Germany + Logilab Paris, France + DFKI GmbH, Germany Impara, Germany - Change Maker, Sweden + Change Maker, Sweden License: - Copyright (C) 2003-2007 + Copyright (C) 2003-2010 - Except when otherwise stated (look for LICENSE files or information at - the beginning of each file) the files in the 'pypy' directory are each - copyrighted by one or more of the following people and organizations: - - Armin Rigo - Samuele Pedroni - Holger Krekel - Christian Tismer - Michael Hudson - Carl Friedrich Bolz - Eric van Riet Paap - Richard Emslie - Anders Chrigstrom - Niklaus Haldimann - Antonio Cuni - Maciek Fijalkowski - Aur?lien Camp?as - Seo Sanghyeon - Alex Martelli - Anders Lehmann - Stephan Diehl - Patrick Maupin - Ludovic Aubry - Bob Ippolito - Adrien Di Mascio - Jacob Hallen - Laura Creighton - Marius Gedminas - Amaury Forgeot d Arc - Boris Feigin - Valentino Volonghi - Bert Freudenberg - Andrew Thompson - Jonathan David Riehl - Amaury Forgeot D Arc - Alexandre Fayolle - Guido van Rossum - - Heinrich-Heine University, Germany - AB Strakt, Sweden - merlinux GmbH, Germany - tismerysoft GmbH, Germany - Logilab Paris, France - DFKI GmbH, Germany +Except when otherwise stated (look for LICENSE files or information at +the beginning of each file) the files in the 'pypy' directory are each +copyrighted by one or more of the following people and organizations: + + Armin Rigo + Maciej Fijalkowski + Carl Friedrich Bolz + Samuele Pedroni + Antonio Cuni + Michael Hudson + Christian Tismer + Holger Krekel + Eric van Riet Paap + Richard Emslie + Anders Chrigstrom + Amaury Forgeot d Arc + Aurelien Campeas + Anders Lehmann + Niklaus Haldimann + Seo Sanghyeon + Leonardo Santagada + Lawrence Oluyede + Jakub Gustak + Guido Wesdorp + Benjamin Peterson + Alexander Schremmer + Niko Matsakis + Ludovic Aubry + Alex Martelli + Toon Verwaest + Stephan Diehl + Adrien Di Mascio + Stefan Schwarzer + Tomek Meka + Patrick Maupin + Jacob Hallen + Laura Creighton + Bob Ippolito + Camillo Bruni + Simon Burton + Bruno Gola + Alexandre Fayolle + Marius Gedminas + Guido van Rossum + Valentino Volonghi + Adrian Kuhn + Paul deGrandis + Gerald Klix + Wanja Saatkamp + Anders Hammarquist + Oscar Nierstrasz + Eugene Oden + Lukas Renggli + Guenter Jantzen + Dinu Gherman + Bartosz Skowron + Georg Brandl + Ben Young + Jean-Paul Calderone + Nicolas Chauvat + Rocco Moretti + Michael Twomey + boria + Jared Grubb + Olivier Dormond + Stuart Williams + Jens-Uwe Mager + Justas Sadzevicius + Mikael Sch?nenberg + Brian Dorsey + Jonathan David Riehl + Beatrice During + Elmo M?ntynen + Andreas Friedge + Alex Gaynor + Anders Qvist + Alan McIntyre + Bert Freudenberg + + Heinrich-Heine University, Germany + Open End AB (formerly AB Strakt), Sweden + merlinux GmbH, Germany + tismerysoft GmbH, Germany + Logilab Paris, France + DFKI GmbH, Germany Impara, Germany - Change Maker, Sweden + Change Maker, Sweden Permission is hereby granted, free of charge, to any person @@ -144,56 +202,44 @@ DEALINGS IN THE SOFTWARE. -License for 'lib-python/2.4.1' and 'lib-python/2.4.1-modified' -============================================================== + +License for 'lib-python/2.5.2' and 'lib-python/2.5.2-modified' +============================================================== Except when otherwise stated (look for LICENSE files or copyright/license information at the beginning of each file) the files -in the 'lib-python/2.4.1' and 'lib-python/2.4.1-modified' directories +in the 'lib-python/2.5.2' and 'lib-python/2.5.2-modified' directories are all copyrighted by the Python Software Foundation and licensed under the Python Software License of which you can find a copy here: -http://www.python.org/doc/Copyright.html +http://www.python.org/doc/Copyright.html -License for files in pypy/modules/unicodedata +License for 'pypy/translator/jvm/src/jna.jar' ============================================= -The following files are from the website of The Unicode Consortium -at . For the terms of use of these files, see -. - - CompositionExclusions-3.2.0.txt - CompositionExclusions-4.1.0.txt - CompositionExclusions-5.0.0.txt - EastAsianWidth-3.2.0.txt - EastAsianWidth-4.1.0.txt - EastAsianWidth-5.0.0.txt - UnicodeData-3.2.0.txt - UnicodeData-4.1.0.txt - UnicodeData-5.0.0.txt - -The following files are derived from files from the above website. The same -terms of use apply: - - UnihanNumeric-3.2.0.txt - UnihanNumeric-4.1.0.txt - UnihanNumeric-5.0.0.txt - -License for pyrex -================= - -Copyright stuff: Pyrex is free of restrictions. You may use, redistribute, -modify and distribute modified versions. - -The latest version of Pyrex can be found here: - - - -Greg Ewing, Computer Science Dept, +--------------------------------------+ -University of Canterbury, | A citizen of NewZealandCorp, a | -Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | -greg at cosc.canterbury.ac.nz +The file 'pypy/translator/jvm/src/jna.jar' is licensed under the GNU +Lesser General Public License of which you can find a copy here: +http://www.gnu.org/licenses/lgpl.html + +License for 'pypy/translator/jvm/src/jasmin.jar' +================================================ + +The file 'pypy/translator/jvm/src/jasmin.jar' is copyright (c) 1996-2004 Jon Meyer +and distributed with permission. The use of Jasmin by PyPy does not imply +that PyPy is endorsed by Jon Meyer nor any of Jasmin's contributors. Furthermore, +the following disclaimer applies to Jasmin: + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + The Debian packaging is (C) 2007, 2008 Alexandre Fayolle , Sylvain Th?nault - and Chris Lamb and is -licensed under the GPL, see `/usr/share/common-licenses/GPL'. + and Chris Lamb +The Debian packaging is (C) 2010 Bartosz Skowron +The package is licensed under the GPL, see `/usr/share/common-licenses/GPL'. From getxsick at codespeak.net Fri Mar 5 04:35:36 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 04:35:36 +0100 (CET) Subject: [pypy-svn] r71771 - pypy/build/ubuntu/debian Message-ID: <20100305033536.AB7C5282BD7@codespeak.net> Author: getxsick Date: Fri Mar 5 04:35:35 2010 New Revision: 71771 Modified: pypy/build/ubuntu/debian/pypy-doc.docs Log: add LICENSE to pypy-docs Modified: pypy/build/ubuntu/debian/pypy-doc.docs ============================================================================== --- pypy/build/ubuntu/debian/pypy-doc.docs (original) +++ pypy/build/ubuntu/debian/pypy-doc.docs Fri Mar 5 04:35:35 2010 @@ -1,2 +1,3 @@ pypy/doc/* README +LICENSE From fijal at codespeak.net Fri Mar 5 04:40:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 04:40:21 +0100 (CET) Subject: [pypy-svn] r71772 - pypy/trunk/pypy/rpython/lltypesystem Message-ID: <20100305034021.9677A282BD9@codespeak.net> Author: fijal Date: Fri Mar 5 04:40:19 2010 New Revision: 71772 Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py Log: Sprinkle purefunction a bit all over the place. Use rgc.ll_shrink_array for slicing last item from the string Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Fri Mar 5 04:40:19 2010 @@ -18,6 +18,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 import rgc # ____________________________________________________________ # @@ -140,6 +141,7 @@ self.ll = LLHelpers self.malloc = mallocunicode + @purefunction def ll_str(self, s): # XXX crazy that this is here, but I don't want to break # rmodel logic @@ -152,6 +154,7 @@ result.chars[i] = cast_primitive(Char, c) return result + @purefunction def ll_encode_latin1(self, s): length = len(s.chars) result = mallocstr(length) @@ -162,7 +165,6 @@ result.chars[i] = cast_primitive(Char, c) return result - class CharRepr(AbstractCharRepr, StringRepr): lowleveltype = Char @@ -236,6 +238,7 @@ class LLHelpers(AbstractLLHelpers): + @purefunction def ll_char_mul(ch, times): if typeOf(ch) is Char: malloc = mallocstr @@ -296,6 +299,7 @@ def ll_strfasthash(s): return s.hash # assumes that the hash is already computed + @purefunction def ll_strconcat(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -304,6 +308,7 @@ s1.copy_contents(s2, newstr, 0, len1, len2) return newstr + @purefunction def ll_strip(s, ch, left, right): s_len = len(s.chars) if s_len == 0: @@ -321,6 +326,7 @@ s.copy_contents(s, result, lpos, 0, r_len) return result + @purefunction def ll_upper(s): s_chars = s.chars s_len = len(s_chars) @@ -337,6 +343,7 @@ i += 1 return result + @purefunction def ll_lower(s): s_chars = s.chars s_len = len(s_chars) @@ -377,6 +384,7 @@ i += 1 return result + @purefunction def ll_strcmp(s1, s2): if not s1 and not s2: return True @@ -419,6 +427,7 @@ return True + @purefunction def ll_startswith(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -434,6 +443,7 @@ return True + @purefunction def ll_endswith(s1, s2): len1 = len(s1.chars) len2 = len(s2.chars) @@ -450,6 +460,7 @@ return True + @purefunction def ll_find_char(s, ch, start, end): i = start if end > len(s.chars): @@ -460,6 +471,7 @@ i += 1 return -1 + @purefunction def ll_rfind_char(s, ch, start, end): if end > len(s.chars): end = len(s.chars) @@ -470,6 +482,7 @@ return i return -1 + @purefunction def ll_count_char(s, ch, start, end): count = 0 i = start @@ -481,6 +494,7 @@ i += 1 return count + @purefunction def ll_find(cls, s1, s2, start, end): """Knuth Morris Prath algorithm for substring match""" len2 = len(s2.chars) @@ -515,6 +529,7 @@ return -1 ll_find = classmethod(ll_find) + @purefunction def ll_rfind(cls, s1, s2, start, end): """Reversed version of ll_find()""" len2 = len(s2.chars) @@ -562,6 +577,7 @@ return -1 ll_rfind = classmethod(ll_rfind) + @purefunction def ll_count(cls, s1, s2, start, end): """Knuth Morris Prath algorithm for substring match""" # XXX more code should be shared with ll_find @@ -640,6 +656,7 @@ i += 1 return result + @purefunction def ll_stringslice_startonly(s1, start): len1 = len(s1.chars) newstr = s1.malloc(len1 - start) @@ -649,6 +666,7 @@ s1.copy_contents(s1, newstr, start, 0, lgt) return newstr + @purefunction def ll_stringslice_startstop(s1, start, stop): if stop >= len(s1.chars): if start == 0: @@ -661,12 +679,11 @@ s1.copy_contents(s1, newstr, start, 0, lgt) return newstr + @purefunction def ll_stringslice_minusone(s1): newlen = len(s1.chars) - 1 - newstr = s1.malloc(newlen) assert newlen >= 0 - s1.copy_contents(s1, newstr, 0, 0, newlen) - return newstr + return rgc.ll_shrink_array(s1, newlen) def ll_split_chr(LIST, s, c): @@ -694,6 +711,7 @@ item.copy_contents(s, item, i, 0, j - i) return res + @purefunction def ll_replace_chr_chr(s, c1, c2): length = len(s.chars) newstr = s.malloc(length) @@ -708,6 +726,7 @@ j += 1 return newstr + @purefunction def ll_contains(s, c): chars = s.chars strlen = len(chars) @@ -718,6 +737,7 @@ i += 1 return False + @purefunction def ll_int(s, base): if not 2 <= base <= 36: raise ValueError From fijal at codespeak.net Fri Mar 5 04:55:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 04:55:11 +0100 (CET) Subject: [pypy-svn] r71773 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305035511.9D510282BDA@codespeak.net> Author: fijal Date: Fri Mar 5 04:55:07 2010 New Revision: 71773 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: don't look into some of those functions Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 04:55:07 2010 @@ -147,6 +147,7 @@ # importhook.unwrap_spec = [ObjSpace, str, W_Root, W_Root, W_Root, int] + at jit.dont_look_inside def absolute_import(space, modulename, baselevel, fromlist_w, tentative): lock = getimportlock(space) lock.acquire_lock() @@ -345,6 +346,7 @@ if pkgdir is not None: space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)])) + at jit.dont_look_inside def load_module(space, w_modulename, find_info, reuse=False): if find_info is None: return @@ -428,6 +430,7 @@ msg = "No module named %s" raise operationerrfmt(space.w_ImportError, msg, modulename) + at jit.dont_look_inside def reload(space, w_module): """Reload the module. The module must have been successfully imported before.""" @@ -625,6 +628,7 @@ code_w.exec_code(space, w_dict, w_dict) + at jit.dont_look_inside def load_source_module(space, w_modulename, w_mod, pathname, source, write_pyc=True): """ @@ -724,6 +728,7 @@ "Non-code object in %s", cpathname) return pycode + at jit.dont_look_inside def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, timestamp, source): """ From fijal at codespeak.net Fri Mar 5 05:03:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 05:03:20 +0100 (CET) Subject: [pypy-svn] r71774 - pypy/branch/import-fiddle/pypy/module/imp Message-ID: <20100305040320.159B451055@codespeak.net> Author: fijal Date: Fri Mar 5 05:03:18 2010 New Revision: 71774 Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py Log: one-if-too-far optimization Modified: pypy/branch/import-fiddle/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/imp/importing.py (original) +++ pypy/branch/import-fiddle/pypy/module/imp/importing.py Fri Mar 5 05:03:18 2010 @@ -220,8 +220,7 @@ first = w_mod tentative = 0 prefix.append(part) - if fromlist_w is not None: - w_path = try_getattr(space, w_mod, w('__path__')) + w_path = try_getattr(space, w_mod, w('__path__')) level += 1 if fromlist_w is not None: From getxsick at codespeak.net Fri Mar 5 05:12:29 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 05:12:29 +0100 (CET) Subject: [pypy-svn] r71775 - in pypy/build/ubuntu/debian: . manpages scripts Message-ID: <20100305041229.CE24C51057@codespeak.net> Author: getxsick Date: Fri Mar 5 05:12:27 2010 New Revision: 71775 Added: pypy/build/ubuntu/debian/manpages/dotviewer.1 pypy/build/ubuntu/debian/manpages/graphserver.1 pypy/build/ubuntu/debian/manpages/sshgraphserver.1 pypy/build/ubuntu/debian/pypy-dotviewer.install pypy/build/ubuntu/debian/pypy-dotviewer.manpages pypy/build/ubuntu/debian/scripts/dotviewer pypy/build/ubuntu/debian/scripts/graphserver pypy/build/ubuntu/debian/scripts/sshgraphserver Modified: pypy/build/ubuntu/debian/changelog pypy/build/ubuntu/debian/control pypy/build/ubuntu/debian/manpages/pypy.1 Log: add pypy-dotviewer package Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Fri Mar 5 05:12:27 2010 @@ -2,10 +2,11 @@ * New upstream release. * New maintainer. - * Only JIT-oriented upstream (e.g. stackless is dropped) - * Rename pypy-translate to rpycompile - * Run tests (-A, lib-python, JIT) - * Switch to dpkg-source 3.0 (native) format + * Only JIT-oriented upstream (e.g. pypy-stackless is dropped). + * Rename pypy-translate to rpycompile. + * Add pypy-dotviewer package. + * Run tests (-A, lib-python, JIT) when binaries are built. + * Switch to dpkg-source 3.0 (native) format. -- Bartosz Skowron Tue, 02 Mar 2010 18:08:37 +0100 Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 5 05:12:27 2010 @@ -53,3 +53,10 @@ . This package provides a version of the standard Python library suitable for use with the PyPy interpreter, both interpreted and translated. + +Package: pypy-dotviewer +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, python-pygame, graphviz +Recommends: pypy | pypy-dev +Description: XXX + Description of the package Added: pypy/build/ubuntu/debian/manpages/dotviewer.1 ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/manpages/dotviewer.1 Fri Mar 5 05:12:27 2010 @@ -0,0 +1,15 @@ +.TH DOTVIEWER 1 "March 5, 2010" +.SH NAME +dotviewer \- PyPy visualization tool. +.SH SYNOPSIS +.B dotviewer +.RI filename.(dot|plain) +.SH OPTIONS +In the first form, show the graph contained in a .dot file. +In the second form, the graph was already compiled to a .plain file. +.SH SEE ALSO +.BR graphserver(1), sshgraphserver(1), pypy (1), +.SH AUTHORS +\fBPyPy\fP was written by the members of the PyPy project . +.PP +This manual page was originally written by Bartosz Skowron . Added: pypy/build/ubuntu/debian/manpages/graphserver.1 ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/manpages/graphserver.1 Fri Mar 5 05:12:27 2010 @@ -0,0 +1,11 @@ +.TH GRAPHSERVER 1 "March 5, 2010" +.SH NAME +graphserver \- PyPy visualization graph server. +.SH DESCRIPTION +From the command-line it's easier to use graphserver instead of this. +.SH SEE ALSO +.BR sshgraphserver (1), dotviewer (1), pypy (1), +.SH AUTHORS +\fBPyPy\fP was written by the members of the PyPy project . +.PP +This manual page was originally written by Bartosz Skowron . Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Fri Mar 5 05:12:27 2010 @@ -35,7 +35,7 @@ .B \-\-info Print translation information about this PyPy executable. .SH SEE ALSO -.BR rpycompile (1), +.BR rpycompile (1), dotviewer (1), graphserver(1), sshgraphserver(1), .SH AUTHORS \fBPyPy\fP was written by the members of the PyPy project . .PP Added: pypy/build/ubuntu/debian/manpages/sshgraphserver.1 ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/manpages/sshgraphserver.1 Fri Mar 5 05:12:27 2010 @@ -0,0 +1,21 @@ +.TH SSHGRAPHSERVER 1 "March 5, 2010" +.SH NAME +sshgraphserver \- PyPy visualization SSH graph server. +.SH SYNOPSIS +.B sshgraphserver +.RI hostname +.SH OPTIONS +other arguments for ssh. +.SH DESCRIPTION +Display locally the graphs that are built by dotviewer on remote machines. + +\fBsshgraphserver\fP logs in to 'hostname' by passing the arguments on the +command-line to ssh. No further configuration is required: it works for all +programs using the dotviewer library as long as they run on 'hostname' under +the same username as the one sshgraphserver logs as. +.SH SEE ALSO +.BR graphserver (1), dotviewer (1), pypy (1), +.SH AUTHORS +\fBPyPy\fP was written by the members of the PyPy project . +.PP +This manual page was originally written by Bartosz Skowron . Added: pypy/build/ubuntu/debian/pypy-dotviewer.install ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/pypy-dotviewer.install Fri Mar 5 05:12:27 2010 @@ -0,0 +1,4 @@ +dotviewer usr/share/pypy-1.2 +debian/scripts/dotviewer usr/bin +debian/scripts/graphserver usr/bin +debian/scripts/sshgraphserver usr/bin Added: pypy/build/ubuntu/debian/pypy-dotviewer.manpages ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/pypy-dotviewer.manpages Fri Mar 5 05:12:27 2010 @@ -0,0 +1,3 @@ +debian/manpages/dotviewer.1 +debian/manpages/graphserver.1 +debian/manpages/sshgraphserver.1 Added: pypy/build/ubuntu/debian/scripts/dotviewer ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/scripts/dotviewer Fri Mar 5 05:12:27 2010 @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/share/pypy-1.2/dotviewer/dotviewer.py "$@" Added: pypy/build/ubuntu/debian/scripts/graphserver ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/scripts/graphserver Fri Mar 5 05:12:27 2010 @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/share/pypy-1.2/dotviewer/graphserver.py "$@" Added: pypy/build/ubuntu/debian/scripts/sshgraphserver ============================================================================== --- (empty file) +++ pypy/build/ubuntu/debian/scripts/sshgraphserver Fri Mar 5 05:12:27 2010 @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/share/pypy-1.2/dotviewer/sshgraphserver.py "$@" From getxsick at codespeak.net Fri Mar 5 05:18:39 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 05:18:39 +0100 (CET) Subject: [pypy-svn] r71776 - pypy/build/ubuntu/debian Message-ID: <20100305041839.0DC2B51057@codespeak.net> Author: getxsick Date: Fri Mar 5 05:18:38 2010 New Revision: 71776 Modified: pypy/build/ubuntu/debian/control Log: set pypy-dotviewer for all architectures Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 5 05:18:38 2010 @@ -55,7 +55,7 @@ use with the PyPy interpreter, both interpreted and translated. Package: pypy-dotviewer -Architecture: any +Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, python-pygame, graphviz Recommends: pypy | pypy-dev Description: XXX From fijal at codespeak.net Fri Mar 5 05:19:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 05:19:12 +0100 (CET) Subject: [pypy-svn] r71777 - pypy/build/ubuntu/debian Message-ID: <20100305041912.DC6FD51058@codespeak.net> Author: fijal Date: Fri Mar 5 05:19:09 2010 New Revision: 71777 Modified: pypy/build/ubuntu/debian/control Log: Kill python in python in python for python here Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 5 05:19:09 2010 @@ -11,14 +11,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib (>= ${source:Version}), python, python-ctypes, gcc, libffi-dev, zlib1g-dev, libbz2-dev Recommends: pypy-doc, python-dev, libgc-dev, llvm-cfe, mono-gmcs, spidermonkey-bin, jasmin-sable, libreadline5-dev Suggests: gcl-dev -Description: the Python in python interpreter, interpreted version - The PyPy project aims to provide a Python implementation of the Python - interpreter. - . - This package provides the interpreted version of PyPy, which requires - a Python interpreter to run. It is able to translate itself using - several backends. To do this, you will need to install some of the - Recommended packages, as well as upgrade your machine with lots of RAM. +Description: PyPy-dev is a compiler writing toolchain. + This package provides the toolchain (including source code) for developing + dynamic languages interpreters in RPython. It can be also used to compile + PyPy's Python interpreter, although we suggest downloading it from trunk + in this case. . Install this package if you want to translate RPython programs, or to build a custom translated version of the PyPy interpreter. @@ -26,33 +23,24 @@ Package: pypy Architecture: i386 Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, libffi, zlib1g, libbz2-dev -Description: the Python in Python interpreter, C backend translation - The PyPy project aims to provide a Python implementation of the Python - interpreter. - . - This package provides the PyPy interpreter compiled using the C backend - and no special additionnal functionality. As such it can be used as another - implementation of the Python language. +Description: PyPy is a python interpreter with Just in time compiler. + This package provides a binary version of the compiled interpreter, together + with several supported modules. Package: pypy-doc Architecture: all Section: doc Description: Documentation for PyPy - The PyPy project aims to provide a Python implementation of the Python - interpreter. - . This package provides documentation for the PyPy interpreter, the translation - process, etc. You will definitely need it if you intend to play with PyPy. + process, etc. You will definitely need it if you intend to play with PyPy, + however all of those docs are online. Package: pypy-lib Architecture: all Recommends: pypy | pypy-dev Description: standard Python library for PyPy - The PyPy project aims to provide a Python implementation of the Python - interpreter. - . This package provides a version of the standard Python library suitable for - use with the PyPy interpreter, both interpreted and translated. + use with the PyPy interpreter. Package: pypy-dotviewer Architecture: all From getxsick at codespeak.net Fri Mar 5 05:36:10 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 05:36:10 +0100 (CET) Subject: [pypy-svn] r71778 - pypy/build/ubuntu/debian/manpages Message-ID: <20100305043610.7A86651057@codespeak.net> Author: getxsick Date: Fri Mar 5 05:36:06 2010 New Revision: 71778 Modified: pypy/build/ubuntu/debian/manpages/pypy.1 Log: update manpage (JIT options) Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Fri Mar 5 05:36:06 2010 @@ -26,6 +26,9 @@ .B \-h, \-\-help Show this help message and exit. .TP +.B \-W +warning control (arg is action:message:category:module:lineno). +.TP .B \-m Library module to be run as a script (terminates option list). .TP @@ -34,6 +37,24 @@ .TP .B \-\-info Print translation information about this PyPy executable. +.TP +.B \-\-jit debug=N +low-level JIT parameter (default 2) +.TP +.B \-\-jit inlining=N +low-level JIT parameter (default False) +.TP +.B \-\-jit optimizer=N +low-level JIT parameter (default 1) +.TP +.B \-\-jit threshold=N +low-level JIT parameter (default 1000) +.TP +.B \-\-jit trace_eagerness=N +low-level JIT parameter (default 200) +.TP +.B \-\-jit trace_limit=N +low-level JIT parameter (default 10000) .SH SEE ALSO .BR rpycompile (1), dotviewer (1), graphserver(1), sshgraphserver(1), .SH AUTHORS From fijal at codespeak.net Fri Mar 5 05:42:13 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 05:42:13 +0100 (CET) Subject: [pypy-svn] r71779 - pypy/build/ubuntu/debian Message-ID: <20100305044213.5A8DC282BD7@codespeak.net> Author: fijal Date: Fri Mar 5 05:42:11 2010 New Revision: 71779 Modified: pypy/build/ubuntu/debian/control Log: Write a description for dotviewer Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 5 05:42:11 2010 @@ -46,5 +46,7 @@ Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, python-pygame, graphviz Recommends: pypy | pypy-dev -Description: XXX - Description of the package +Description: A viewer for dot files and graphs generated by PyPy + This package provides a tool that can display .dot files in animated + manner. It's widely used by various PyPy's debugging tools, like + JIT assembler viewer, flowgraph viewer etc. From getxsick at codespeak.net Fri Mar 5 05:45:54 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 05:45:54 +0100 (CET) Subject: [pypy-svn] r71780 - pypy/build/ubuntu/debian Message-ID: <20100305044554.5A74251055@codespeak.net> Author: getxsick Date: Fri Mar 5 05:45:52 2010 New Revision: 71780 Modified: pypy/build/ubuntu/debian/copyright Log: add license for unicodedata Modified: pypy/build/ubuntu/debian/copyright ============================================================================== --- pypy/build/ubuntu/debian/copyright (original) +++ pypy/build/ubuntu/debian/copyright Fri Mar 5 05:45:52 2010 @@ -237,6 +237,29 @@ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +License for 'pypy/module/unicodedata' +===================================== + +The following files are from the website of The Unicode Consortium +at http://www.unicode.org/. For the terms of use of these files, see +http://www.unicode.org/terms_of_use.html + + CompositionExclusions-3.2.0.txt + CompositionExclusions-4.1.0.txt + CompositionExclusions-5.0.0.txt + EastAsianWidth-3.2.0.txt + EastAsianWidth-4.1.0.txt + EastAsianWidth-5.0.0.txt + UnicodeData-3.2.0.txt + UnicodeData-4.1.0.txt + UnicodeData-5.0.0.txt + +The following files are derived from files from the above website. The same +terms of use apply. + UnihanNumeric-3.2.0.txt + UnihanNumeric-4.1.0.txt + UnihanNumeric-5.0.0.txt + The Debian packaging is (C) 2007, 2008 Alexandre Fayolle , Sylvain Th?nault From fijal at codespeak.net Fri Mar 5 05:50:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 05:50:17 +0100 (CET) Subject: [pypy-svn] r71781 - pypy/build/ubuntu/debian/manpages Message-ID: <20100305045017.4E98B51057@codespeak.net> Author: fijal Date: Fri Mar 5 05:50:15 2010 New Revision: 71781 Modified: pypy/build/ubuntu/debian/manpages/pypy.1 Log: a bit update Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Fri Mar 5 05:50:15 2010 @@ -1,11 +1,11 @@ .TH PYPY 1 "March 4, 2010" .SH NAME -pypy \- PyPy Python interpreter compiled using the C backend. +pypy \- PyPy's Python interpreter with a just in time compiler. .SH SYNOPSIS .B pypy .RI [options] .SH DESCRIPTION -\fBpypy\fP is a Python interpreter compiled using the C backend. +\fBpypy\fP is a Python interpreter with a just in time compiler. .SH OPTIONS .TP .B \-i @@ -39,7 +39,7 @@ Print translation information about this PyPy executable. .TP .B \-\-jit debug=N -low-level JIT parameter (default 2) +Set the verbosity of the jit (default: 2, 0 - turn it off) .TP .B \-\-jit inlining=N low-level JIT parameter (default False) From getxsick at codespeak.net Fri Mar 5 05:55:08 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 05:55:08 +0100 (CET) Subject: [pypy-svn] r71782 - in pypy/build/ubuntu/debian: . manpages Message-ID: <20100305045508.95FE051058@codespeak.net> Author: getxsick Date: Fri Mar 5 05:55:06 2010 New Revision: 71782 Modified: pypy/build/ubuntu/debian/Makefile.in pypy/build/ubuntu/debian/manpages/pypy.1 Log: set --jit-debug=0 for translation Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Fri Mar 5 05:55:06 2010 @@ -1,7 +1,7 @@ TARGET=pypy/translator/goal/targetpypystandalone TRANSLATE=pypy/translator/goal/translate.py -TRANSLATEOPTS=--batch --source -Ojit +TRANSLATEOPTS=--batch --source -Ojit --jit-debug=0 TARGETOPTS=%(TARGETOPTS)s PREFIX=%(PREFIX)s LOGIC=-o logic Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Fri Mar 5 05:55:06 2010 @@ -39,22 +39,22 @@ Print translation information about this PyPy executable. .TP .B \-\-jit debug=N -Set the verbosity of the jit (default: 2, 0 - turn it off) +Set the verbosity of the jit (default: 0) .TP .B \-\-jit inlining=N -low-level JIT parameter (default False) +low-level JIT parameter (default: False) .TP .B \-\-jit optimizer=N -low-level JIT parameter (default 1) +low-level JIT parameter (default: 1) .TP .B \-\-jit threshold=N -low-level JIT parameter (default 1000) +low-level JIT parameter (default: 1000) .TP .B \-\-jit trace_eagerness=N -low-level JIT parameter (default 200) +low-level JIT parameter (default: 200) .TP .B \-\-jit trace_limit=N -low-level JIT parameter (default 10000) +low-level JIT parameter (default: 10000) .SH SEE ALSO .BR rpycompile (1), dotviewer (1), graphserver(1), sshgraphserver(1), .SH AUTHORS From getxsick at codespeak.net Fri Mar 5 06:01:52 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 06:01:52 +0100 (CET) Subject: [pypy-svn] r71783 - pypy/build/ubuntu/debian/manpages Message-ID: <20100305050152.072AA51059@codespeak.net> Author: getxsick Date: Fri Mar 5 06:01:49 2010 New Revision: 71783 Modified: pypy/build/ubuntu/debian/manpages/dotviewer.1 Log: update description Modified: pypy/build/ubuntu/debian/manpages/dotviewer.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/dotviewer.1 (original) +++ pypy/build/ubuntu/debian/manpages/dotviewer.1 Fri Mar 5 06:01:49 2010 @@ -1,12 +1,16 @@ .TH DOTVIEWER 1 "March 5, 2010" .SH NAME -dotviewer \- PyPy visualization tool. +dotviewer \- A viewer for dot files and graphs generated by PyPy .SH SYNOPSIS .B dotviewer .RI filename.(dot|plain) .SH OPTIONS In the first form, show the graph contained in a .dot file. In the second form, the graph was already compiled to a .plain file. +.SH DESCRIPTION +\fBdotviewer\fP provides a tool that can display .dot files in animated +manner. It's widely used by various PyPy's debugging tools, like +JIT assembler viewer, flowgraph viewer etc. .SH SEE ALSO .BR graphserver(1), sshgraphserver(1), pypy (1), .SH AUTHORS From fijal at codespeak.net Fri Mar 5 06:07:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 06:07:10 +0100 (CET) Subject: [pypy-svn] r71784 - in pypy/trunk/pypy/jit: backend backend/llsupport backend/test metainterp Message-ID: <20100305050710.AA100282BD6@codespeak.net> Author: fijal Date: Fri Mar 5 06:07:07 2010 New Revision: 71784 Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/backend/test/test_random.py pypy/trunk/pypy/jit/metainterp/executor.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py Log: Revert 71737:71735. Apparently it broke some tests (test_sqlite in cpython as well as translate). I cannot explain why, so I revert it. To be investigated on a branch probably. Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Fri Mar 5 06:07:07 2010 @@ -14,15 +14,11 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr -class CPUMutableContainer(object): - _overflow_flag = False - class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): - self.mutable = CPUMutableContainer() assert type(opts) is not bool self.opts = opts @@ -54,19 +50,12 @@ self._setup_on_leave_jitted_translated() else: self._setup_on_leave_jitted_untranslated() - self.class_sizes = {} - - def set_overflow_flag(self, val): - self.mutable._overflow_flag = val - - def get_overflow_error(self): - return self.mutable._overflow_flag def setup(self): pass def set_class_sizes(self, class_sizes): - self.class_sizes.update(class_sizes) + self.class_sizes = class_sizes def _setup_prebuilt_error(self, prefix, Class): if self.rtyper is not None: # normal case @@ -116,8 +105,8 @@ v_i = _exception_emulator[1] _exception_emulator[0] = 0 _exception_emulator[1] = 0 - self.mutable.saved_exception = tp_i - self.mutable.saved_exc_value = self._cast_int_to_gcref(v_i) + self.saved_exception = tp_i + self.saved_exc_value = self._cast_int_to_gcref(v_i) self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -144,8 +133,8 @@ # from now on, the state is again consistent -- no more RPython # exception is set. The following code produces a write barrier # in the assignment to self.saved_exc_value, as needed. - self.mutable.saved_exception = exception - self.mutable.saved_exc_value = exc_value + self.saved_exception = exception + self.saved_exc_value = exc_value self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -183,14 +172,14 @@ return rffi.cast(lltype.Signed, f) def get_exception(self): - return self.mutable.saved_exception + return self.saved_exception def get_exc_value(self): - return self.mutable.saved_exc_value + return self.saved_exc_value def clear_exception(self): - self.mutable.saved_exception = 0 - self.mutable.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.saved_exception = 0 + self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) # ------------------- helpers and descriptions -------------------- Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Fri Mar 5 06:07:07 2010 @@ -8,14 +8,9 @@ portal_calldescr = None done_with_this_frame_int_v = -1 - _overflow_flag = False - def __init__(self): self.fail_descr_list = [] - def _freeze_(self): - return True - def get_fail_descr_number(self, descr): assert isinstance(descr, history.AbstractFailDescr) n = descr.index @@ -118,12 +113,6 @@ def get_zero_division_error(self): raise NotImplementedError - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, val): - self._overflow_flag = val - @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/trunk/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/test_random.py (original) +++ pypy/trunk/pypy/jit/backend/test/test_random.py Fri Mar 5 06:07:07 2010 @@ -264,8 +264,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu.get_overflow_flag(): # overflow detected - builder.cpu.set_overflow_flag(False) + if builder.cpu._overflow_flag: # overflow detected + del builder.cpu._overflow_flag op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including Modified: pypy/trunk/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/executor.py (original) +++ pypy/trunk/pypy/jit/metainterp/executor.py Fri Mar 5 06:07:07 2010 @@ -145,7 +145,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_sub_ovf(cpu, box1, box2): @@ -158,7 +158,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_mul_ovf(cpu, box1, box2): @@ -171,7 +171,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) # ---------- Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Fri Mar 5 06:07:07 2010 @@ -1898,8 +1898,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu.get_overflow_flag(): - self.cpu.set_overflow_flag(False) + if self.cpu._overflow_flag: + self.cpu._overflow_flag = False frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From fijal at codespeak.net Fri Mar 5 06:20:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 06:20:58 +0100 (CET) Subject: [pypy-svn] r71785 - in pypy/branch/import-fiddle/pypy/jit: backend backend/llsupport backend/test metainterp Message-ID: <20100305052058.1031E282BD7@codespeak.net> Author: fijal Date: Fri Mar 5 06:20:55 2010 New Revision: 71785 Modified: pypy/branch/import-fiddle/pypy/jit/backend/llsupport/llmodel.py pypy/branch/import-fiddle/pypy/jit/backend/model.py pypy/branch/import-fiddle/pypy/jit/backend/test/test_random.py pypy/branch/import-fiddle/pypy/jit/metainterp/executor.py pypy/branch/import-fiddle/pypy/jit/metainterp/pyjitpl.py Log: Merge 71784 from trunk, so I can isolate potential issues Modified: pypy/branch/import-fiddle/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/import-fiddle/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/import-fiddle/pypy/jit/backend/llsupport/llmodel.py Fri Mar 5 06:20:55 2010 @@ -14,15 +14,11 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr -class CPUMutableContainer(object): - _overflow_flag = False - class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): - self.mutable = CPUMutableContainer() assert type(opts) is not bool self.opts = opts @@ -54,19 +50,12 @@ self._setup_on_leave_jitted_translated() else: self._setup_on_leave_jitted_untranslated() - self.class_sizes = {} - - def set_overflow_flag(self, val): - self.mutable._overflow_flag = val - - def get_overflow_error(self): - return self.mutable._overflow_flag def setup(self): pass def set_class_sizes(self, class_sizes): - self.class_sizes.update(class_sizes) + self.class_sizes = class_sizes def _setup_prebuilt_error(self, prefix, Class): if self.rtyper is not None: # normal case @@ -116,8 +105,8 @@ v_i = _exception_emulator[1] _exception_emulator[0] = 0 _exception_emulator[1] = 0 - self.mutable.saved_exception = tp_i - self.mutable.saved_exc_value = self._cast_int_to_gcref(v_i) + self.saved_exception = tp_i + self.saved_exc_value = self._cast_int_to_gcref(v_i) self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -144,8 +133,8 @@ # from now on, the state is again consistent -- no more RPython # exception is set. The following code produces a write barrier # in the assignment to self.saved_exc_value, as needed. - self.mutable.saved_exception = exception - self.mutable.saved_exc_value = exc_value + self.saved_exception = exception + self.saved_exc_value = exc_value self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -183,14 +172,14 @@ return rffi.cast(lltype.Signed, f) def get_exception(self): - return self.mutable.saved_exception + return self.saved_exception def get_exc_value(self): - return self.mutable.saved_exc_value + return self.saved_exc_value def clear_exception(self): - self.mutable.saved_exception = 0 - self.mutable.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.saved_exception = 0 + self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) # ------------------- helpers and descriptions -------------------- Modified: pypy/branch/import-fiddle/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/import-fiddle/pypy/jit/backend/model.py (original) +++ pypy/branch/import-fiddle/pypy/jit/backend/model.py Fri Mar 5 06:20:55 2010 @@ -8,14 +8,9 @@ portal_calldescr = None done_with_this_frame_int_v = -1 - _overflow_flag = False - def __init__(self): self.fail_descr_list = [] - def _freeze_(self): - return True - def get_fail_descr_number(self, descr): assert isinstance(descr, history.AbstractFailDescr) n = descr.index @@ -118,12 +113,6 @@ def get_zero_division_error(self): raise NotImplementedError - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, val): - self._overflow_flag = val - @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/import-fiddle/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/import-fiddle/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/import-fiddle/pypy/jit/backend/test/test_random.py Fri Mar 5 06:20:55 2010 @@ -264,8 +264,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu.get_overflow_flag(): # overflow detected - builder.cpu.set_overflow_flag(False) + if builder.cpu._overflow_flag: # overflow detected + del builder.cpu._overflow_flag op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including Modified: pypy/branch/import-fiddle/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/import-fiddle/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/import-fiddle/pypy/jit/metainterp/executor.py Fri Mar 5 06:20:55 2010 @@ -145,7 +145,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_sub_ovf(cpu, box1, box2): @@ -158,7 +158,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_mul_ovf(cpu, box1, box2): @@ -171,7 +171,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) # ---------- Modified: pypy/branch/import-fiddle/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/import-fiddle/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/import-fiddle/pypy/jit/metainterp/pyjitpl.py Fri Mar 5 06:20:55 2010 @@ -1898,8 +1898,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu.get_overflow_flag(): - self.cpu.set_overflow_flag(False) + if self.cpu._overflow_flag: + self.cpu._overflow_flag = False frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From fijal at codespeak.net Fri Mar 5 06:21:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 06:21:43 +0100 (CET) Subject: [pypy-svn] r71786 - in pypy/branch/cleanup-warnings/pypy/jit: backend backend/llsupport backend/test metainterp Message-ID: <20100305052143.4DB265105A@codespeak.net> Author: fijal Date: Fri Mar 5 06:21:41 2010 New Revision: 71786 Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py pypy/branch/cleanup-warnings/pypy/jit/backend/model.py pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py Log: Merge 71784 from trunk Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/llsupport/llmodel.py Fri Mar 5 06:21:41 2010 @@ -14,15 +14,11 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr -class CPUMutableContainer(object): - _overflow_flag = False - class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): - self.mutable = CPUMutableContainer() assert type(opts) is not bool self.opts = opts @@ -54,19 +50,12 @@ self._setup_on_leave_jitted_translated() else: self._setup_on_leave_jitted_untranslated() - self.class_sizes = {} - - def set_overflow_flag(self, val): - self.mutable._overflow_flag = val - - def get_overflow_error(self): - return self.mutable._overflow_flag def setup(self): pass def set_class_sizes(self, class_sizes): - self.class_sizes.update(class_sizes) + self.class_sizes = class_sizes def _setup_prebuilt_error(self, prefix, Class): if self.rtyper is not None: # normal case @@ -116,8 +105,8 @@ v_i = _exception_emulator[1] _exception_emulator[0] = 0 _exception_emulator[1] = 0 - self.mutable.saved_exception = tp_i - self.mutable.saved_exc_value = self._cast_int_to_gcref(v_i) + self.saved_exception = tp_i + self.saved_exc_value = self._cast_int_to_gcref(v_i) self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -144,8 +133,8 @@ # from now on, the state is again consistent -- no more RPython # exception is set. The following code produces a write barrier # in the assignment to self.saved_exc_value, as needed. - self.mutable.saved_exception = exception - self.mutable.saved_exc_value = exc_value + self.saved_exception = exception + self.saved_exc_value = exc_value self.pos_exception = pos_exception self.pos_exc_value = pos_exc_value @@ -183,14 +172,14 @@ return rffi.cast(lltype.Signed, f) def get_exception(self): - return self.mutable.saved_exception + return self.saved_exception def get_exc_value(self): - return self.mutable.saved_exc_value + return self.saved_exc_value def clear_exception(self): - self.mutable.saved_exception = 0 - self.mutable.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) + self.saved_exception = 0 + self.saved_exc_value = lltype.nullptr(llmemory.GCREF.TO) # ------------------- helpers and descriptions -------------------- Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/model.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/model.py Fri Mar 5 06:21:41 2010 @@ -8,14 +8,9 @@ portal_calldescr = None done_with_this_frame_int_v = -1 - _overflow_flag = False - def __init__(self): self.fail_descr_list = [] - def _freeze_(self): - return True - def get_fail_descr_number(self, descr): assert isinstance(descr, history.AbstractFailDescr) n = descr.index @@ -118,12 +113,6 @@ def get_zero_division_error(self): raise NotImplementedError - def get_overflow_flag(self): - return self._overflow_flag - - def set_overflow_flag(self, val): - self._overflow_flag = val - @staticmethod def sizeof(S): raise NotImplementedError Modified: pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/backend/test/test_random.py Fri Mar 5 06:21:41 2010 @@ -264,8 +264,8 @@ fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) - if builder.cpu.get_overflow_flag(): # overflow detected - builder.cpu.set_overflow_flag(False) + if builder.cpu._overflow_flag: # overflow detected + del builder.cpu._overflow_flag op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/executor.py Fri Mar 5 06:21:41 2010 @@ -145,7 +145,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_sub_ovf(cpu, box1, box2): @@ -158,7 +158,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) def do_int_mul_ovf(cpu, box1, box2): @@ -171,7 +171,7 @@ z = 0 else: ovf = False - cpu.set_overflow_flag(ovf) + cpu._overflow_flag = ovf return BoxInt(z) # ---------- Modified: pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/cleanup-warnings/pypy/jit/metainterp/pyjitpl.py Fri Mar 5 06:21:41 2010 @@ -1898,8 +1898,8 @@ def handle_overflow_error(self): frame = self.framestack[-1] - if self.cpu.get_overflow_flag(): - self.cpu.set_overflow_flag(False) + if self.cpu._overflow_flag: + self.cpu._overflow_flag = False frame.generate_guard(frame.pc, rop.GUARD_OVERFLOW, None, []) return self.raise_overflow_error() else: From dan at codespeak.net Fri Mar 5 07:52:42 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Fri, 5 Mar 2010 07:52:42 +0100 (CET) Subject: [pypy-svn] r71787 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100305065242.6EC0651057@codespeak.net> Author: dan Date: Fri Mar 5 07:52:39 2010 New Revision: 71787 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: More tests, fixed some logic in DynamicType as a result. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Fri Mar 5 07:52:39 2010 @@ -42,14 +42,9 @@ elif self.name == code: return space.w_True else: - xxx - return space.w_False + raise OperationError(space.w_TypeError, space.wrap("data type not understood")) except OperationError, e: - xxx - return space.w_False - except TypeError, e: - xxx - return space.w_False #FIXME: need to throw applevel type error + raise OperationError(space.w_TypeError, space.wrap("data type not understood")) descr_eq.unwrap_spec = ['self', ObjSpace, W_Root] DynamicType.typedef = TypeDef('dtype', __eq__ = interp2app(DynamicType.descr_eq), Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Fri Mar 5 07:52:39 2010 @@ -281,6 +281,27 @@ assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) +class AppTestDType(object): + def setup_class(cls): + cls.space = gettestobjspace(usemodules=('micronumpy',)) + #FIXME: need DynamicType.__new__/__init__ to best test this + def test_eq(self): + from numpy import zeros + + a = zeros((4,), dtype=int) + assert a.dtype == int + assert a.dtype == 'i' + assert a.dtype == 'int32' + raises((TypeError,), a.dtype, 'in') + raises((TypeError,), a.dtype.__eq__, 3) + + b = zeros((4,), dtype=float) + assert b.dtype == float + assert b.dtype == 'd' + assert b.dtype == 'float64' + raises((TypeError,), b.dtype, 'flo') + raises((TypeError,), b.dtype.__eq__, 3) + class TestDType(object): def test_lookups(self, space): from pypy.module.micronumpy.dtype import retrieve_dtype From arigo at codespeak.net Fri Mar 5 09:50:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 09:50:22 +0100 (CET) Subject: [pypy-svn] r71788 - in pypy/trunk/pypy: jit/backend/llsupport jit/backend/llsupport/test rpython/memory/gctransform translator/c/gcc translator/c/gcc/test translator/c/gcc/test/elf Message-ID: <20100305085022.5A24F282BD7@codespeak.net> Author: arigo Date: Fri Mar 5 09:50:21 2010 New Revision: 71788 Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py pypy/trunk/pypy/translator/c/gcc/instruction.py pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Log: Simplify a bit the encoding used for the location of asmgcroots: by separating the EBP+N and EBP-N cases we avoid the issue of encoding possibly-negative integers. Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Fri Mar 5 09:50:21 2010 @@ -202,10 +202,10 @@ """Handles locating the stack roots in the assembler. This is the class supporting --gcrootfinder=asmgcc. """ - LOC_NOWHERE = 0 - LOC_REG = 1 - LOC_EBP_BASED = 2 - LOC_ESP_BASED = 3 + LOC_REG = 0 + LOC_ESP_PLUS = 1 + LOC_EBP_PLUS = 2 + LOC_EBP_MINUS = 3 GCMAP_ARRAY = rffi.CArray(llmemory.Address) CALLSHAPE_ARRAY = rffi.CArray(rffi.UCHAR) @@ -252,37 +252,38 @@ lltype.free(oldgcmap, flavor='raw') def get_basic_shape(self): - return [self.LOC_EBP_BASED | 4, # return addr: at 4(%ebp) - self.LOC_EBP_BASED | (-4), # saved %ebx: at -4(%ebp) - self.LOC_EBP_BASED | (-8), # saved %esi: at -8(%ebp) - self.LOC_EBP_BASED | (-12), # saved %edi: at -12(%ebp) - self.LOC_EBP_BASED | 0, # saved %ebp: at (%ebp) + return [self.LOC_EBP_PLUS | 4, # return addr: at 4(%ebp) + self.LOC_EBP_MINUS | 4, # saved %ebx: at -4(%ebp) + self.LOC_EBP_MINUS | 8, # saved %esi: at -8(%ebp) + self.LOC_EBP_MINUS | 12, # saved %edi: at -12(%ebp) + self.LOC_EBP_PLUS | 0, # saved %ebp: at (%ebp) 0] def add_ebp_offset(self, shape, offset): assert (offset & 3) == 0 - shape.append(self.LOC_EBP_BASED | offset) + if offset >= 0: + encoded = self.LOC_EBP_PLUS | offset + else: + encoded = self.LOC_EBP_MINUS | (-offset) + shape.append(encoded) def add_ebx(self, shape): - shape.append(self.LOC_REG | 0) + shape.append(self.LOC_REG | 4) def add_esi(self, shape): - shape.append(self.LOC_REG | 4) + shape.append(self.LOC_REG | 8) def add_edi(self, shape): - shape.append(self.LOC_REG | 8) + shape.append(self.LOC_REG | 12) def add_ebp(self, shape): - shape.append(self.LOC_REG | 12) + shape.append(self.LOC_REG | 16) def compress_callshape(self, shape): # Similar to compress_callshape() in trackgcroot.py. XXX a bit slowish result = [] for loc in shape: - if loc < 0: - loc = (-loc) * 2 - 1 - else: - loc = loc * 2 + assert loc >= 0 flag = 0 while loc >= 0x80: result.append(int(loc & 0x7F) | flag) Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Fri Mar 5 09:50:21 2010 @@ -64,29 +64,28 @@ def frame_pos(n): return -4*(4+n) gcrootmap = GcRootMap_asmgcc() - num1 = frame_pos(1) + num1 = frame_pos(-5) num2 = frame_pos(55) shape = gcrootmap.get_basic_shape() gcrootmap.add_ebp_offset(shape, num1) gcrootmap.add_ebp_offset(shape, num2) - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2] + assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3] gcrootmap.add_ebx(shape) - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1] + assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4] gcrootmap.add_esi(shape) - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1] + assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8] gcrootmap.add_edi(shape) - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1, 8|1] + assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12] gcrootmap.add_ebp(shape) - assert shape == [6, -2, -6, -10, 2, 0, num1|2, num2|2, 0|1, 4|1, 8|1, 12|1] + assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12, 16] # shapeaddr = gcrootmap.compress_callshape(shape) PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) - num1a = -2*(num1|2)-1 - num2a = ((-2*(num2|2)-1) >> 7) | 128 - num2b = (-2*(num2|2)-1) & 127 - for i, expected in enumerate([26, 18, 10, 2, - num2a, num2b, num1a, 0, 4, 19, 11, 3, 12]): + num2a = ((-num2|3) >> 7) | 128 + num2b = (-num2|3) & 127 + for i, expected in enumerate([16, 12, 8, 4, + num2a, num2b, num1|2, 0, 2, 15, 11, 7, 6]): assert p[i] == expected # retaddr = rffi.cast(llmemory.Address, 1234567890) @@ -97,14 +96,14 @@ # # the same as before, but enough times to trigger a few resizes expected_shapeaddr = {} - for i in range(1, 600): + for i in range(1, 700): shape = gcrootmap.get_basic_shape() gcrootmap.add_ebp_offset(shape, frame_pos(i)) shapeaddr = gcrootmap.compress_callshape(shape) expected_shapeaddr[i] = shapeaddr retaddr = rffi.cast(llmemory.Address, 123456789 + i) gcrootmap.put(retaddr, shapeaddr) - for i in range(1, 600): + for i in range(1, 700): expected_retaddr = rffi.cast(llmemory.Address, 123456789 + i) assert gcrootmap._gcmap[i*2+0] == expected_retaddr assert gcrootmap._gcmap[i*2+1] == expected_shapeaddr[i] Modified: pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/asmgcroot.py Fri Mar 5 09:50:21 2010 @@ -313,29 +313,32 @@ on the integer 'location' that describes it. All locations are computed based on information saved by the 'callee'. """ + ll_assert(location >= 0, "negative location") kind = location & LOC_MASK + offset = location & ~ LOC_MASK if kind == LOC_REG: # register - reg = location >> 2 - ll_assert(0 <= reg < CALLEE_SAVED_REGS, "bad register location") + if location == LOC_NOWHERE: + return llmemory.NULL + reg = (location >> 2) - 1 + ll_assert(reg < CALLEE_SAVED_REGS, "bad register location") return callee.regs_stored_at[reg] - elif kind == LOC_ESP_BASED: # in the caller stack frame at N(%esp) - offset = location & ~ LOC_MASK - ll_assert(offset >= 0, "bad %esp-based location") + elif kind == LOC_ESP_PLUS: # in the caller stack frame at N(%esp) esp_in_caller = callee.frame_address + 4 return esp_in_caller + offset - elif kind == LOC_EBP_BASED: # in the caller stack frame at N(%ebp) - offset = location & ~ LOC_MASK + elif kind == LOC_EBP_PLUS: # in the caller stack frame at N(%ebp) ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0] return ebp_in_caller + offset - else: - return llmemory.NULL + else: # kind == LOC_EBP_MINUS: at -N(%ebp) + ebp_in_caller = callee.regs_stored_at[INDEX_OF_EBP].address[0] + return ebp_in_caller - offset -LOC_NOWHERE = 0 -LOC_REG = 1 -LOC_EBP_BASED = 2 -LOC_ESP_BASED = 3 +LOC_REG = 0 +LOC_ESP_PLUS = 1 +LOC_EBP_PLUS = 2 +LOC_EBP_MINUS = 3 LOC_MASK = 0x03 +LOC_NOWHERE = LOC_REG | 0 # ____________________________________________________________ @@ -440,9 +443,6 @@ break value = (value - 0x80) << 7 self.addr = addr - if value & 1: - value = ~ value - value = value >> 1 return value # ____________________________________________________________ Modified: pypy/trunk/pypy/translator/c/gcc/instruction.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/instruction.py (original) +++ pypy/trunk/pypy/translator/c/gcc/instruction.py Fri Mar 5 09:50:21 2010 @@ -1,13 +1,21 @@ -LOC_NOWHERE = 0 -LOC_REG = 1 -LOC_EBP_BASED = 2 -LOC_ESP_BASED = 3 +LOC_REG = 0 +LOC_ESP_PLUS = 1 +LOC_EBP_PLUS = 2 +LOC_EBP_MINUS = 3 LOC_MASK = 0x03 +LOC_NOWHERE = LOC_REG | 0 -def frameloc(base, offset): - assert base in (LOC_EBP_BASED, LOC_ESP_BASED) +def frameloc_esp(offset): + assert offset >= 0 assert offset % 4 == 0 - return base | offset + return LOC_ESP_PLUS | offset + +def frameloc_ebp(offset): + assert offset % 4 == 0 + if offset >= 0: + return LOC_EBP_PLUS | offset + else: + return LOC_EBP_MINUS | (-offset) class SomeNewValue(object): @@ -40,12 +48,12 @@ # try to use esp-relative addressing ofs_from_esp = framesize + self.ofs_from_frame_end if ofs_from_esp % 2 == 0: - return frameloc(LOC_ESP_BASED, ofs_from_esp) + return frameloc_esp(ofs_from_esp) # we can get an odd value if the framesize is marked as bogus # by visit_andl() assert uses_frame_pointer ofs_from_ebp = self.ofs_from_frame_end + 4 - return frameloc(LOC_EBP_BASED, ofs_from_ebp) + return frameloc_ebp(ofs_from_ebp) class Insn(object): Modified: pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/elf/track4.s Fri Mar 5 09:50:21 2010 @@ -26,7 +26,7 @@ movl %esi, %ebx movl $nonsense, %esi call foobar - ;; expected {4(%ebp) | -8(%ebp), %ebx, -4(%ebp), (%ebp) | -12(%ebp), 4(%esp)} + ;; expected {4(%ebp) | -8(%ebp), %ebx, -4(%ebp), (%ebp) | 4(%esp), -12(%ebp)} addl %edi, %eax movl 4(%esp), %eax movl %ebx, %esi Modified: pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s Fri Mar 5 09:50:21 2010 @@ -13,7 +13,7 @@ movl $globalptr2, (%esp) pushl $0 call foobar - ;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | -4(%ebp), 4(%esp)} + ;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | 4(%esp), -4(%ebp)} popl %eax #APP /* GCROOT -4(%ebp) */ Modified: pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/test/test_trackgcroot.py Fri Mar 5 09:50:21 2010 @@ -3,7 +3,8 @@ from pypy.translator.c.gcc.trackgcroot import format_location from pypy.translator.c.gcc.trackgcroot import format_callshape from pypy.translator.c.gcc.trackgcroot import LOC_NOWHERE, LOC_REG -from pypy.translator.c.gcc.trackgcroot import LOC_EBP_BASED, LOC_ESP_BASED +from pypy.translator.c.gcc.trackgcroot import LOC_EBP_PLUS, LOC_EBP_MINUS +from pypy.translator.c.gcc.trackgcroot import LOC_ESP_PLUS from pypy.translator.c.gcc.trackgcroot import ElfAssemblerParser from pypy.translator.c.gcc.trackgcroot import DarwinAssemblerParser from pypy.translator.c.gcc.trackgcroot import compress_callshape @@ -16,32 +17,31 @@ def test_format_location(): assert format_location(LOC_NOWHERE) == '?' - assert format_location(LOC_REG | (0<<2)) == '%ebx' - assert format_location(LOC_REG | (1<<2)) == '%esi' - assert format_location(LOC_REG | (2<<2)) == '%edi' - assert format_location(LOC_REG | (3<<2)) == '%ebp' - assert format_location(LOC_EBP_BASED + 0) == '(%ebp)' - assert format_location(LOC_EBP_BASED + 4) == '4(%ebp)' - assert format_location(LOC_EBP_BASED - 4) == '-4(%ebp)' - assert format_location(LOC_ESP_BASED + 0) == '(%esp)' - assert format_location(LOC_ESP_BASED + 4) == '4(%esp)' - assert format_location(LOC_ESP_BASED - 4) == '-4(%esp)' + assert format_location(LOC_REG | (1<<2)) == '%ebx' + assert format_location(LOC_REG | (2<<2)) == '%esi' + assert format_location(LOC_REG | (3<<2)) == '%edi' + assert format_location(LOC_REG | (4<<2)) == '%ebp' + assert format_location(LOC_EBP_PLUS + 0) == '(%ebp)' + assert format_location(LOC_EBP_PLUS + 4) == '4(%ebp)' + assert format_location(LOC_EBP_MINUS + 4) == '-4(%ebp)' + assert format_location(LOC_ESP_PLUS + 0) == '(%esp)' + assert format_location(LOC_ESP_PLUS + 4) == '4(%esp)' def test_format_callshape(): expected = ('{4(%ebp) ' # position of the return address '| 8(%ebp), 12(%ebp), 16(%ebp), 20(%ebp) ' # 4 saved regs '| 24(%ebp), 28(%ebp)}') # GC roots - assert format_callshape((LOC_EBP_BASED+4, - LOC_EBP_BASED+8, - LOC_EBP_BASED+12, - LOC_EBP_BASED+16, - LOC_EBP_BASED+20, - LOC_EBP_BASED+24, - LOC_EBP_BASED+28)) == expected + assert format_callshape((LOC_EBP_PLUS+4, + LOC_EBP_PLUS+8, + LOC_EBP_PLUS+12, + LOC_EBP_PLUS+16, + LOC_EBP_PLUS+20, + LOC_EBP_PLUS+24, + LOC_EBP_PLUS+28)) == expected def test_compress_callshape(): - shape = (1, -3, 0x1234, -0x5678, 0x234567, - -0x765432, 0x61626364, -0x41424344) + shape = (1, 127, 0x1234, 0x5678, 0x234567, + 0x765432, 0x61626364, 0x41424344) bytes = list(compress_callshape(shape)) print bytes assert len(bytes) == 1+1+2+3+4+4+5+5+1 Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Fri Mar 5 09:50:21 2010 @@ -9,9 +9,11 @@ from pypy.translator.c.gcc.instruction import InsnGCROOT from pypy.translator.c.gcc.instruction import InsnStackAdjust from pypy.translator.c.gcc.instruction import InsnCannotFollowEsp -from pypy.translator.c.gcc.instruction import LocalVar, somenewvalue, frameloc +from pypy.translator.c.gcc.instruction import LocalVar, somenewvalue +from pypy.translator.c.gcc.instruction import frameloc_esp, frameloc_ebp from pypy.translator.c.gcc.instruction import LOC_REG, LOC_NOWHERE, LOC_MASK -from pypy.translator.c.gcc.instruction import LOC_EBP_BASED, LOC_ESP_BASED +from pypy.translator.c.gcc.instruction import LOC_EBP_PLUS, LOC_EBP_MINUS +from pypy.translator.c.gcc.instruction import LOC_ESP_PLUS class FunctionGcRootTracker(object): skip = 0 @@ -69,9 +71,9 @@ if self.is_stack_bottom: retaddr = LOC_NOWHERE # end marker for asmgcroot.py elif self.uses_frame_pointer: - retaddr = frameloc(LOC_EBP_BASED, 4) + retaddr = frameloc_ebp(4) else: - retaddr = frameloc(LOC_ESP_BASED, insn.framesize) + retaddr = frameloc_esp(insn.framesize) shape = [retaddr] # the first gcroots are always the ones corresponding to # the callee-saved registers @@ -736,7 +738,7 @@ EBP = '%ebp' EAX = '%eax' CALLEE_SAVE_REGISTERS = ['%ebx', '%esi', '%edi', '%ebp'] - REG2LOC = dict((_reg, LOC_REG | (_i<<2)) + REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2)) for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS)) OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])' LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)' @@ -808,7 +810,7 @@ EBP = 'ebp' EAX = 'eax' CALLEE_SAVE_REGISTERS = ['ebx', 'esi', 'edi', 'ebp'] - REG2LOC = dict((_reg, LOC_REG | (_i<<2)) + REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2)) for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS)) TOP_OF_STACK = 'DWORD PTR [esp]' @@ -1453,19 +1455,24 @@ # in the stack frame at an address relative to either %esp or %ebp. # The last two bits of the location number are used to tell the cases # apart; see format_location(). + assert loc >= 0 kind = loc & LOC_MASK - if kind == LOC_NOWHERE: - return '?' - elif kind == LOC_REG: - reg = loc >> 2 - assert 0 <= reg <= 3 + if kind == LOC_REG: + if loc == LOC_NOWHERE: + return '?' + reg = (loc >> 2) - 1 return ElfFunctionGcRootTracker.CALLEE_SAVE_REGISTERS[reg] else: - if kind == LOC_EBP_BASED: + offset = loc & ~ LOC_MASK + if kind == LOC_EBP_PLUS: result = '(%ebp)' - else: + elif kind == LOC_EBP_MINUS: + result = '(%ebp)' + offset = -offset + elif kind == LOC_ESP_PLUS: result = '(%esp)' - offset = loc & ~ LOC_MASK + else: + assert 0, kind if offset != 0: result = str(offset) + result return result @@ -1531,10 +1538,7 @@ shape.insert(5, 0) result = [] for loc in shape: - if loc < 0: - loc = (-loc) * 2 - 1 - else: - loc = loc * 2 + assert loc >= 0 flag = 0 while loc >= 0x80: result.append(int(loc & 0x7F) | flag) @@ -1557,9 +1561,6 @@ if b < 0x80: break value = (value - 0x80) << 7 - if value & 1: - value = ~ value - value = value >> 1 result.append(value) result.reverse() assert result[5] == 0 From arigo at codespeak.net Fri Mar 5 10:01:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 10:01:41 +0100 (CET) Subject: [pypy-svn] r71789 - in pypy/trunk/pypy/jit/backend/llsupport: . test Message-ID: <20100305090141.D8030282BD6@codespeak.net> Author: arigo Date: Fri Mar 5 10:01:40 2010 New Revision: 71789 Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Log: Avoid one pass in compress_callshape() by computing the encoded "unsigned char" numbers directly. Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Fri Mar 5 10:01:40 2010 @@ -252,51 +252,51 @@ lltype.free(oldgcmap, flavor='raw') def get_basic_shape(self): - return [self.LOC_EBP_PLUS | 4, # return addr: at 4(%ebp) - self.LOC_EBP_MINUS | 4, # saved %ebx: at -4(%ebp) - self.LOC_EBP_MINUS | 8, # saved %esi: at -8(%ebp) - self.LOC_EBP_MINUS | 12, # saved %edi: at -12(%ebp) - self.LOC_EBP_PLUS | 0, # saved %ebp: at (%ebp) - 0] + return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 4(%ebp) + chr(self.LOC_EBP_MINUS | 4), # saved %ebx: at -4(%ebp) + chr(self.LOC_EBP_MINUS | 8), # saved %esi: at -8(%ebp) + chr(self.LOC_EBP_MINUS | 12), # saved %edi: at -12(%ebp) + chr(self.LOC_EBP_PLUS | 0), # saved %ebp: at (%ebp) + chr(0)] + + def _encode_num(self, shape, number): + assert number >= 0 + flag = 0 + while number >= 0x80: + shape.append(chr((number & 0x7F) | flag)) + flag = 0x80 + number >>= 7 + shape.append(chr(number | flag)) def add_ebp_offset(self, shape, offset): assert (offset & 3) == 0 if offset >= 0: - encoded = self.LOC_EBP_PLUS | offset + num = self.LOC_EBP_PLUS | offset else: - encoded = self.LOC_EBP_MINUS | (-offset) - shape.append(encoded) + num = self.LOC_EBP_MINUS | (-offset) + self._encode_num(shape, num) def add_ebx(self, shape): - shape.append(self.LOC_REG | 4) + shape.append(chr(self.LOC_REG | 4)) def add_esi(self, shape): - shape.append(self.LOC_REG | 8) + shape.append(chr(self.LOC_REG | 8)) def add_edi(self, shape): - shape.append(self.LOC_REG | 12) + shape.append(chr(self.LOC_REG | 12)) def add_ebp(self, shape): - shape.append(self.LOC_REG | 16) + shape.append(chr(self.LOC_REG | 16)) def compress_callshape(self, shape): - # Similar to compress_callshape() in trackgcroot.py. XXX a bit slowish - result = [] - for loc in shape: - assert loc >= 0 - flag = 0 - while loc >= 0x80: - result.append(int(loc & 0x7F) | flag) - flag = 0x80 - loc >>= 7 - result.append(int(loc) | flag) + # Similar to compress_callshape() in trackgcroot.py. # XXX so far, we always allocate a new small array (we could regroup # them inside bigger arrays) and we never try to share them. - length = len(result) + length = len(shape) compressed = lltype.malloc(self.CALLSHAPE_ARRAY, length, flavor='raw') for i in range(length): - compressed[length-1-i] = rffi.cast(rffi.UCHAR, result[i]) + compressed[length-1-i] = rffi.cast(rffi.UCHAR, shape[i]) return llmemory.cast_ptr_to_adr(compressed) Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Fri Mar 5 10:01:40 2010 @@ -65,27 +65,32 @@ return -4*(4+n) gcrootmap = GcRootMap_asmgcc() num1 = frame_pos(-5) + num1a = num1|2 num2 = frame_pos(55) + num2a = ((-num2|3) >> 7) | 128 + num2b = (-num2|3) & 127 shape = gcrootmap.get_basic_shape() gcrootmap.add_ebp_offset(shape, num1) gcrootmap.add_ebp_offset(shape, num2) - assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3] + assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a]) gcrootmap.add_ebx(shape) - assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4] + assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a, + 4]) gcrootmap.add_esi(shape) - assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8] + assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a, + 4, 8]) gcrootmap.add_edi(shape) - assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12] + assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a, + 4, 8, 12]) gcrootmap.add_ebp(shape) - assert shape == [6, 7, 11, 15, 2, 0, num1|2, -num2|3, 4, 8, 12, 16] + assert shape == map(chr, [6, 7, 11, 15, 2, 0, num1a, num2b, num2a, + 4, 8, 12, 16]) # shapeaddr = gcrootmap.compress_callshape(shape) PCALLSHAPE = lltype.Ptr(GcRootMap_asmgcc.CALLSHAPE_ARRAY) p = llmemory.cast_adr_to_ptr(shapeaddr, PCALLSHAPE) - num2a = ((-num2|3) >> 7) | 128 - num2b = (-num2|3) & 127 for i, expected in enumerate([16, 12, 8, 4, - num2a, num2b, num1|2, 0, 2, 15, 11, 7, 6]): + num2a, num2b, num1a, 0, 2, 15, 11, 7, 6]): assert p[i] == expected # retaddr = rffi.cast(llmemory.Address, 1234567890) From arigo at codespeak.net Fri Mar 5 11:23:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 11:23:42 +0100 (CET) Subject: [pypy-svn] r71790 - in pypy/trunk/pypy/config: . test Message-ID: <20100305102342.427E6282BD6@codespeak.net> Author: arigo Date: Fri Mar 5 11:23:40 2010 New Revision: 71790 Modified: pypy/trunk/pypy/config/pypyoption.py pypy/trunk/pypy/config/test/test_pypyoption.py Log: 'withshadowtracking' is incompatible with 'withinlineddict'. Remove it explicitly and fix the test. It would have been better if it complained -- now I'm unsure which of the two options was picked up in my pypy-c test builds... Modified: pypy/trunk/pypy/config/pypyoption.py ============================================================================== --- pypy/trunk/pypy/config/pypyoption.py (original) +++ pypy/trunk/pypy/config/pypyoption.py Fri Mar 5 11:23:40 2010 @@ -325,7 +325,6 @@ config.objspace.opcodes.suggest(CALL_LIKELY_BUILTIN=True) if level in ['2', '3', 'jit']: config.objspace.opcodes.suggest(CALL_METHOD=True) - config.objspace.std.suggest(withshadowtracking=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) 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 Fri Mar 5 11:23:40 2010 @@ -47,7 +47,7 @@ def test_set_pypy_opt_level(): conf = get_pypy_config() set_pypy_opt_level(conf, '2') - assert conf.objspace.std.withshadowtracking + assert conf.objspace.std.withsharingdict conf = get_pypy_config() set_pypy_opt_level(conf, '0') assert not conf.objspace.std.newshortcut From arigo at codespeak.net Fri Mar 5 12:00:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 12:00:31 +0100 (CET) Subject: [pypy-svn] r71791 - pypy/build/bot2/pypybuildbot Message-ID: <20100305110031.CDA65282BD6@codespeak.net> Author: arigo Date: Fri Mar 5 12:00:29 2010 New Revision: 71791 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Add JITMACOSX32. Not run every night so far, but only manually. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 5 12:00:29 2010 @@ -94,6 +94,7 @@ JITLINUX32 = "pypy-c-jit-linux-x86-32" OJITLINUX32 = "pypy-c-Ojit-no-jit-linux-x86-32" +JITMACOSX32 = "pypy-c-jit-macosx-x86-32" JITONLYLINUX32 = "jitonly-own-linux-x86-32" JITBENCH = "jit-benchmark-linux-x86-32" @@ -175,6 +176,12 @@ 'factory' : pypyJITTranslatedTestFactory, 'category' : 'jit', }, + {"name" : JITMACOSX32, + "slavenames": ["minime"], + 'builddir' : JITMACOSX32, + 'factory' : pypyJITTranslatedTestFactory, + 'category' : 'jit', + }, {"name": JITONLYLINUX32, "slavenames": ["bigdogvm1"], "builddir": JITONLYLINUX32, From arigo at codespeak.net Fri Mar 5 12:03:28 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 12:03:28 +0100 (CET) Subject: [pypy-svn] r71792 - pypy/build/bot2/pypybuildbot Message-ID: <20100305110328.DE033282BD6@codespeak.net> Author: arigo Date: Fri Mar 5 12:03:27 2010 New Revision: 71792 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Also add JITWIN32. Similarly, this is not run nightly for now. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 5 12:03:27 2010 @@ -95,6 +95,7 @@ JITLINUX32 = "pypy-c-jit-linux-x86-32" OJITLINUX32 = "pypy-c-Ojit-no-jit-linux-x86-32" JITMACOSX32 = "pypy-c-jit-macosx-x86-32" +JITWIN32 = "pypy-c-jit-win-x86-32" JITONLYLINUX32 = "jitonly-own-linux-x86-32" JITBENCH = "jit-benchmark-linux-x86-32" @@ -182,6 +183,12 @@ 'factory' : pypyJITTranslatedTestFactory, 'category' : 'jit', }, + {"name" : JITWIN32, + "slavenames": ["bigboard"], + 'builddir' : JITWIN32, + 'factory' : pypyJITTranslatedTestFactory, + 'category' : 'jit', + }, {"name": JITONLYLINUX32, "slavenames": ["bigdogvm1"], "builddir": JITONLYLINUX32, From arigo at codespeak.net Fri Mar 5 13:24:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 13:24:27 +0100 (CET) Subject: [pypy-svn] r71793 - pypy/build/bot2/pypybuildbot Message-ID: <20100305122427.2171251055@codespeak.net> Author: arigo Date: Fri Mar 5 13:24:25 2010 New Revision: 71793 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Picking a random slave is not really what we want; let's pick the first available one instead. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 5 13:24:25 2010 @@ -1,6 +1,7 @@ from buildbot.scheduler import Nightly from buildbot.buildslave import BuildSlave from buildbot.status.html import WebStatus +from buildbot.process.builder import Builder # I really wanted to pass logPath to Site @@ -29,6 +30,10 @@ StatusResourceBuilder.ping = my_ping # Disabled. +# Picking a random slave is not really what we want; +# let's pick the first available one instead. +Builder.CHOOSE_SLAVES_RANDOMLY = False + status = WebStatus(httpPortNumber, allowForce=True) From arigo at codespeak.net Fri Mar 5 13:38:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 13:38:15 +0100 (CET) Subject: [pypy-svn] r71794 - pypy/trunk/pypy/rpython/lltypesystem Message-ID: <20100305123815.027F451055@codespeak.net> Author: arigo Date: Fri Mar 5 13:38:14 2010 New Revision: 71794 Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py Log: Can't do that. You are mutating the string passed as an argument! Revert this part of r71772. (Incidentally, r71784 is a pointless revert because non-JITted pypy-c's fail in the same way. My guess is that the cause was really r71772.) Modified: pypy/trunk/pypy/rpython/lltypesystem/rstr.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rstr.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rstr.py Fri Mar 5 13:38:14 2010 @@ -18,7 +18,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 import rgc # ____________________________________________________________ # @@ -682,9 +681,10 @@ @purefunction def ll_stringslice_minusone(s1): newlen = len(s1.chars) - 1 + newstr = s1.malloc(newlen) assert newlen >= 0 - return rgc.ll_shrink_array(s1, newlen) - + s1.copy_contents(s1, newstr, 0, 0, newlen) + return newstr def ll_split_chr(LIST, s, c): chars = s.chars From arigo at codespeak.net Fri Mar 5 13:43:14 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 13:43:14 +0100 (CET) Subject: [pypy-svn] r71795 - in pypy/branch/guard-value-counting/pypy: jit/metainterp jit/metainterp/test module/pypyjit Message-ID: <20100305124314.1F9E651055@codespeak.net> Author: arigo Date: Fri Mar 5 13:43:12 2010 New Revision: 71795 Modified: pypy/branch/guard-value-counting/pypy/jit/metainterp/compile.py pypy/branch/guard-value-counting/pypy/jit/metainterp/optimizeopt.py pypy/branch/guard-value-counting/pypy/jit/metainterp/pyjitpl.py pypy/branch/guard-value-counting/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/guard-value-counting/pypy/module/pypyjit/interp_jit.py Log: Check in my working copy. That branch will probably be abandonned and maybe restarted some day. Modified: pypy/branch/guard-value-counting/pypy/jit/metainterp/compile.py ============================================================================== --- pypy/branch/guard-value-counting/pypy/jit/metainterp/compile.py (original) +++ pypy/branch/guard-value-counting/pypy/jit/metainterp/compile.py Fri Mar 5 13:43:12 2010 @@ -202,35 +202,90 @@ ], } + class ResumeDescr(AbstractFailDescr): def __init__(self, original_greenkey): self.original_greenkey = original_greenkey def _clone_if_mutable(self): raise NotImplementedError -class ResumeGuardDescr(ResumeDescr): + +class PreOptGuardDescr(ResumeDescr): + """The descr of any guard operation before optimization.""" + + # this class also gets the following attributes stored by resume.py code + pd_snapshot = None + pd_frame_info_list = None + + # XXX temp + def __setattr__(self, attr, value): + assert not attr.startswith('rd_') + ResumeDescr.__setattr__(self, attr, value) + + def get_final_descr(self, opnum, metainterp_sd): + if opnum == rop.GUARD_TRUE: + cls = ResumeGuardTrueDescr + elif opnum == rop.GUARD_FALSE: + cls = ResumeGuardFalseDescr + elif opnum == rop.GUARD_VALUE: + cls = ResumeGuardValueDescr + elif opnum == rop.GUARD_NO_EXCEPTION or opnum == rop.GUARD_EXCEPTION: + cls = ResumeGuardExcDescr + elif opnum == rop.GUARD_NO_OVERFLOW: + cls = ResumeGuardNoOverflowDescr + elif opnum == rop.GUARD_NONNULL: + cls = ResumeGuardNonNullDescr + elif opnum == rop.GUARD_ISNULL: + cls = ResumeGuardIsNullDescr + elif opnum == rop.GUARD_NOT_FORCED: + cls = ResumeGuardForcedDescr + else: + cls = ResumeGuardDefaultDescr + return cls(metainterp_sd, self.original_greenkey) + + def get_final_descr_guard_value_bool(self, metainterp_sd): + return ResumeGuardValueBoolDescr(metainterp_sd, self.original_greenkey) + + def _clone_if_mutable(self): + res = PreOptGuardDescr(self.original_greenkey) + # XXX a bit ugly to have to list them here + res.rd_snapshot = self.rd_snapshot + res.rd_frame_info_list = self.rd_frame_info_list + return res + + +class BaseResumeGuardDescr(ResumeDescr): + """The base class for the descr of guard operations after optimization.""" counter = 0 + # this class also gets the following attributes stored by resume.py code - rd_snapshot = None rd_frame_info_list = None rd_numb = None rd_consts = None rd_virtuals = None rd_pendingfields = None + # XXX temp + def __setattr__(self, attr, value): + assert not attr.startswith('pd_') + ResumeDescr.__setattr__(self, attr, value) + def __init__(self, metainterp_sd, original_greenkey): ResumeDescr.__init__(self, original_greenkey) self.metainterp_sd = metainterp_sd def store_final_boxes(self, guard_op, boxes): + guard_op.descr = self guard_op.fail_args = boxes - self.guard_opnum = guard_op.opnum def handle_fail(self, metainterp_sd): from pypy.jit.metainterp.pyjitpl import MetaInterp metainterp = MetaInterp(metainterp_sd) return metainterp.handle_guard_failure(self) + def prepare_resume(self, metainterp): + raise NotImplementedError + def compile_and_attach(self, metainterp, new_loop): # We managed to create a bridge. Attach the new operations # to the corrsponding guard_op and compile from there @@ -241,18 +296,47 @@ new_loop.operations) - def _clone_if_mutable(self): - res = self.__class__(self.metainterp_sd, self.original_greenkey) - # XXX a bit ugly to have to list them all here - res.rd_snapshot = self.rd_snapshot - res.rd_frame_info_list = self.rd_frame_info_list - res.rd_numb = self.rd_numb - res.rd_consts = self.rd_consts - res.rd_virtuals = self.rd_virtuals - res.rd_pendingfields = self.rd_pendingfields - return res +# we have all the following classes as a way to save one word in each +# instance + +class ResumeGuardDefaultDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + pass + +class ResumeGuardTrueDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_true() + +class ResumeGuardFalseDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_false() + +class ResumeGuardExcDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_exc() + +class ResumeGuardNoOverflowDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_no_overflow() + +class ResumeGuardNonNullDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_non_null() + +class ResumeGuardIsNullDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + metainterp.prepare_resume_guard_is_null() + +# for GUARD_VALUE detected to operate on a bool +ResumeGuardValueBoolDescr = ResumeGuardDefaultDescr + +class ResumeGuardValueDescr(BaseResumeGuardDescr): + def prepare_resume(self, metainterp): + pass # xxx + -class ResumeGuardForcedDescr(ResumeGuardDescr): +class ResumeGuardForcedDescr(BaseResumeGuardDescr): + """A version of ResumeGuardDescr for GUARD_NOT_FORCED.""" def handle_fail(self, metainterp_sd): from pypy.jit.metainterp.pyjitpl import MetaInterp @@ -317,6 +401,10 @@ class ResumeFromInterpDescr(ResumeDescr): + """This is used by pyjitpl as the ResumeDescr for cases where tracing + started from the interpreter, at a loop boundary, instead of from a + guard failure. + """ def __init__(self, original_greenkey, redkey): ResumeDescr.__init__(self, original_greenkey) self.redkey = redkey Modified: pypy/branch/guard-value-counting/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/guard-value-counting/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/guard-value-counting/pypy/jit/metainterp/optimizeopt.py Fri Mar 5 13:43:12 2010 @@ -549,18 +549,11 @@ def store_final_boxes_in_guard(self, op): pendingfields = self.heap_op_optimizer.force_lazy_setfields_for_guard() - descr = op.descr - assert isinstance(descr, compile.ResumeGuardDescr) - modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo) - newboxes = modifier.finish(self.values, pendingfields) - if len(newboxes) > self.metainterp_sd.options.failargs_limit: # XXX be careful here - raise compile.GiveUp - descr.store_final_boxes(op, newboxes) - # + pdescr = op.descr + assert isinstance(pdescr, compile.PreOptGuardDescr) + metainterp_sd = self.metainterp_sd + # Hack: turn guard_value(bool) into guard_true/guard_false. - # This is done after the operation is emitted, to let - # store_final_boxes_in_guard set the guard_opnum field - # of the descr to the original rop.GUARD_VALUE. if op.opnum == rop.GUARD_VALUE and op.args[0] in self.bool_boxes: constvalue = op.args[1].getint() if constvalue == 0: @@ -571,6 +564,16 @@ raise AssertionError("uh?") op.opnum = opnum op.args = [op.args[0]] + rdescr = pdescr.get_final_descr_guard_value_bool(metainterp_sd) + else: + rdescr = pdescr.get_final_descr(op.opnum, metainterp_sd) + + modifier = resume.ResumeDataVirtualAdder(pdescr, rdescr, + self.resumedata_memo) + newboxes = modifier.finish(self.values, pendingfields) + if len(newboxes) > self.metainterp_sd.options.failargs_limit: # XXX be careful here + raise compile.GiveUp + rdescr.store_final_boxes(op, newboxes) def optimize_default(self, op): if op.is_always_pure(): @@ -654,15 +657,14 @@ # replace the original guard with a guard_value old_guard_op = self.newoperations[value.last_guard_index] old_opnum = old_guard_op.opnum - old_guard_op.opnum = op.opnum + old_guard_op.opnum = rop.GUARD_VALUE old_guard_op.args = [old_guard_op.args[0], op.args[1]] - if old_opnum == rop.GUARD_NONNULL: - # hack hack hack. Change the guard_opnum on - # old_guard_op.descr so that when resuming, - # the operation is not skipped by pyjitpl.py. - descr = old_guard_op.descr - assert isinstance(descr, compile.ResumeGuardDescr) - descr.guard_opnum = rop.GUARD_NONNULL_CLASS + # hack hack hack. Change the guard_opnum on + # old_guard_op.descr so that when resuming, + # the operation is not skipped by pyjitpl.py. + descr = old_guard_op.descr + assert isinstance(descr, compile.ResumeGuardDescr) + descr.guard_opnum = rop.GUARD_VALUE emit_operation = False constbox = op.args[1] assert isinstance(constbox, Const) @@ -699,7 +701,7 @@ # old_guard_op.descr so that when resuming, # the operation is not skipped by pyjitpl.py. descr = old_guard_op.descr - assert isinstance(descr, compile.ResumeGuardDescr) + assert isinstance(descr, compile.BaseResumeGuardDescr) descr.guard_opnum = rop.GUARD_NONNULL_CLASS emit_operation = False if emit_operation: Modified: pypy/branch/guard-value-counting/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/guard-value-counting/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/guard-value-counting/pypy/jit/metainterp/pyjitpl.py Fri Mar 5 13:43:12 2010 @@ -1016,12 +1016,8 @@ moreargs = list(extraargs) metainterp_sd = metainterp.staticdata original_greenkey = metainterp.resumekey.original_greenkey - if opnum == rop.GUARD_NOT_FORCED: - resumedescr = compile.ResumeGuardForcedDescr(metainterp_sd, - original_greenkey) - else: - resumedescr = compile.ResumeGuardDescr(metainterp_sd, - original_greenkey) + resumedescr = compile.PreOptGuardDescr(metainterp_sd, + original_greenkey) guard_op = metainterp.history.record(opnum, moreargs, None, descr=resumedescr) virtualizable_boxes = None Modified: pypy/branch/guard-value-counting/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/guard-value-counting/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/guard-value-counting/pypy/jit/metainterp/test/test_optimizeopt.py Fri Mar 5 13:43:12 2010 @@ -13,6 +13,8 @@ from pypy.jit.metainterp import executor, compile, resume from pypy.jit.metainterp.resoperation import rop, opname, ResOperation from pypy.jit.metainterp.test.oparser import pure_parse +from pypy.jit.metainterp.compile import PreOptGuardDescr +from pypy.jit.metainterp.compile import BaseResumeGuardDescr class FakeFrame(object): parent_resumedata_snapshot = None @@ -36,31 +38,33 @@ self.globaldata = Fake() def test_store_final_boxes_in_guard(): - from pypy.jit.metainterp.compile import ResumeGuardDescr + from pypy.jit.metainterp.compile import ResumeGuardTrueDescr from pypy.jit.metainterp.resume import tag, TAGBOX b0 = BoxInt() b1 = BoxInt() opt = optimizeopt.Optimizer(FakeMetaInterpStaticData(LLtypeMixin.cpu), None) - fdescr = ResumeGuardDescr(None, None) - op = ResOperation(rop.GUARD_TRUE, [], None, descr=fdescr) + pdescr = PreOptGuardDescr(None) + op = ResOperation(rop.GUARD_TRUE, [], None, descr=pdescr) # setup rd data fi0 = resume.FrameInfo(None, FakeFrame("code0", 1, 2)) - fdescr.rd_frame_info_list = resume.FrameInfo(fi0, + pdescr.pd_frame_info_list = resume.FrameInfo(fi0, FakeFrame("code1", 3, -1)) snapshot0 = resume.Snapshot(None, [b0]) - fdescr.rd_snapshot = resume.Snapshot(snapshot0, [b1]) + pdescr.pd_snapshot = resume.Snapshot(snapshot0, [b1]) # opt.store_final_boxes_in_guard(op) + rdescr = op.descr + assert isinstance(rdescr, ResumeGuardTrueDescr) if op.fail_args == [b0, b1]: - assert fdescr.rd_numb.nums == [tag(1, TAGBOX)] - assert fdescr.rd_numb.prev.nums == [tag(0, TAGBOX)] + assert rdescr.rd_numb.nums == [tag(1, TAGBOX)] + assert rdescr.rd_numb.prev.nums == [tag(0, TAGBOX)] else: assert op.fail_args == [b1, b0] - assert fdescr.rd_numb.nums == [tag(0, TAGBOX)] - assert fdescr.rd_numb.prev.nums == [tag(1, TAGBOX)] - assert fdescr.rd_virtuals is None - assert fdescr.rd_consts == [] + assert rdescr.rd_numb.nums == [tag(0, TAGBOX)] + assert rdescr.rd_numb.prev.nums == [tag(1, TAGBOX)] + assert rdescr.rd_virtuals is None + assert rdescr.rd_consts == [] def test_sharing_field_lists_of_virtual(): class FakeOptimizer(object): @@ -205,15 +209,14 @@ # ____________________________________________________________ -class Storage(compile.ResumeGuardDescr): +class Storage(PreOptGuardDescr): "for tests." def __init__(self, metainterp_sd=None, original_greenkey=None): self.metainterp_sd = metainterp_sd self.original_greenkey = original_greenkey - def store_final_boxes(self, op, boxes): - op.fail_args = boxes def __eq__(self, other): - return type(self) is type(other) # xxx obscure + # xxx obscure, for equaloplists() + return self is other or isinstance(other, BaseResumeGuardDescr) class BaseTestOptimizeOpt(BaseTest): @@ -221,8 +224,8 @@ if fail_args is None: return None descr = Storage() - descr.rd_frame_info_list = resume.FrameInfo(None, FakeFrame()) - descr.rd_snapshot = resume.Snapshot(None, fail_args) + descr.pd_frame_info_list = resume.FrameInfo(None, FakeFrame()) + descr.pd_snapshot = resume.Snapshot(None, fail_args) return descr def assert_equal(self, optimized, expected): @@ -1796,41 +1799,46 @@ self.optimize_loop(ops, "Not, Not, Not, Not, Not", expected) def test_merge_guard_nonnull_guard_class(self): + self.make_fail_descr() ops = """ [p1, i0, i1, i2, p2] - guard_nonnull(p1) [i0] + guard_nonnull(p1, descr=fdescr) [i0] i3 = int_add(i1, i2) guard_class(p1, ConstClass(node_vtable)) [i1] jump(p2, i0, i1, i3, p2) """ expected = """ [p1, i0, i1, i2, p2] - guard_nonnull_class(p1, ConstClass(node_vtable)) [i0] + guard_nonnull_class(p1, ConstClass(node_vtable), descr=fdescr) [i0] i3 = int_add(i1, i2) jump(p2, i0, i1, i3, p2) """ self.optimize_loop(ops, "Not, Not, Not, Not, Not", expected) + self.check_expanded_fail_descr("i0", rop.GUARD_NONNULL_CLASS) def test_merge_guard_nonnull_guard_value(self): + self.make_fail_descr() ops = """ [p1, i0, i1, i2, p2] - guard_nonnull(p1) [i0] + guard_nonnull(p1, descr=fdescr) [i0] i3 = int_add(i1, i2) guard_value(p1, ConstPtr(myptr)) [i1] jump(p2, i0, i1, i3, p2) """ expected = """ [p1, i0, i1, i2, p2] - guard_value(p1, ConstPtr(myptr)) [i0] + guard_value(p1, ConstPtr(myptr), descr=fdescr) [i0] i3 = int_add(i1, i2) jump(p2, i0, i1, i3, p2) """ self.optimize_loop(ops, "Not, Not, Not, Not, Not", expected) + self.check_expanded_fail_descr("i0", rop.GUARD_VALUE) def test_merge_guard_nonnull_guard_class_guard_value(self): + self.make_fail_descr() ops = """ [p1, i0, i1, i2, p2] - guard_nonnull(p1) [i0] + guard_nonnull(p1, descr=fdescr) [i0] i3 = int_add(i1, i2) guard_class(p1, ConstClass(node_vtable)) [i2] i4 = int_sub(i3, 1) @@ -1839,12 +1847,13 @@ """ expected = """ [p1, i0, i1, i2, p2] - guard_value(p1, ConstPtr(myptr)) [i0] + guard_value(p1, ConstPtr(myptr), descr=fdescr) [i0] i3 = int_add(i1, i2) i4 = int_sub(i3, 1) jump(p2, i0, i1, i4, p2) """ self.optimize_loop(ops, "Not, Not, Not, Not, Not", expected) + self.check_expanded_fail_descr("i0", rop.GUARD_VALUE) def test_guard_class_oois(self): ops = """ @@ -2043,10 +2052,11 @@ _variables_equal(fieldbox, fieldvalue.strip(), strict=False) index += 1 - def check_expanded_fail_descr(self, expectedtext): + def check_expanded_fail_descr(self, expectedtext, guard_opnum): guard_op, = [op for op in self.loop.operations if op.is_guard()] fail_args = guard_op.fail_args fdescr = guard_op.descr + assert fdescr.guard_opnum == guard_opnum reader = resume.ResumeDataReader(fdescr, fail_args, MyMetaInterp(self.cpu)) boxes = reader.consume_boxes() @@ -2071,7 +2081,7 @@ jump(1, i3) """ self.optimize_loop(ops, 'Not, Not', expected) - self.check_expanded_fail_descr('15, i3') + self.check_expanded_fail_descr('15, i3', rop.GUARD_TRUE) def test_expand_fail_2(self): self.make_fail_descr() @@ -2091,7 +2101,7 @@ self.optimize_loop(ops, 'Not, Not', expected) self.check_expanded_fail_descr('''ptr where ptr is a node_vtable, valuedescr=i2 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_3(self): self.make_fail_descr() @@ -2115,7 +2125,7 @@ self.check_expanded_fail_descr('''p1, i3 where p1 is a node_vtable, valuedescr=1, nextdescr=p2 where p2 is a node_vtable, valuedescr=i2, nextdescr=p3 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_4(self): for arg in ['p1', 'p1,i2', 'i2,p1', 'p1,p2', 'p2,p1', @@ -2142,8 +2152,8 @@ self.optimize_loop(ops % arg, 'Not, Not, Not', expected) self.check_expanded_fail_descr('''i3, %s, i3 where p1 is a node_vtable, valuedescr=i2, nextdescr=p2 - where p2 is a node_vtable, valuedescr=i2''' % arg) - + where p2 is a node_vtable, valuedescr=i2''' % arg, + rop.GUARD_TRUE) def test_expand_fail_5(self): self.make_fail_descr() @@ -2167,7 +2177,7 @@ self.check_expanded_fail_descr('''p1, i3, p2, i4 where p1 is a node_vtable, valuedescr=i4, nextdescr=p2 where p2 is a node_vtable, valuedescr=i2, nextdescr=p1 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_6(self): self.make_fail_descr() @@ -2187,7 +2197,7 @@ Not, Not''', expected) self.check_expanded_fail_descr('''p0 where p0 is a node_vtable, valuedescr=i1b - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_varray(self): self.make_fail_descr() @@ -2208,7 +2218,7 @@ self.optimize_loop(ops, 'Not', expected) self.check_expanded_fail_descr('''p1 where p1 is a varray arraydescr: 25, i1 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_vstruct(self): self.make_fail_descr() @@ -2230,7 +2240,7 @@ self.optimize_loop(ops, 'Not, Not', expected) self.check_expanded_fail_descr('''p2 where p2 is a vstruct ssize, adescr=i1, bdescr=p1 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_v_all_1(self): self.make_fail_descr() @@ -2271,7 +2281,7 @@ where p6s is a vstruct ssize, adescr=ia, bdescr=p7v where p5s is a vstruct ssize, adescr=i2, bdescr=p7v where p7v is a node_vtable, valuedescr=iv - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_lazy_setfield_1(self): self.make_fail_descr() @@ -2297,7 +2307,7 @@ self.check_expanded_fail_descr(''' p1.nextdescr = p2 where p2 is a node_vtable, valuedescr=i2 - ''') + ''', rop.GUARD_TRUE) def test_expand_fail_lazy_setfield_2(self): self.make_fail_descr() @@ -2322,7 +2332,7 @@ self.check_expanded_fail_descr(''' ConstPtr(myptr).nextdescr = p2 where p2 is a node_vtable, valuedescr=i2 - ''') + ''', rop.GUARD_TRUE) class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin): @@ -2621,7 +2631,7 @@ self.check_expanded_fail_descr('''p2, p1 where p1 is a node_vtable, nextdescr=p1b where p1b is a node_vtable, valuedescr=i1 - ''') + ''', rop.GUARD_NOT_FORCED) def test_vref_virtual_and_lazy_setfield(self): self.make_fail_descr() @@ -2660,7 +2670,7 @@ where p2 is a jit_virtual_ref_vtable, virtualtokendescr=i3, virtualrefindexdescr=2 where p1 is a node_vtable, nextdescr=p1b where p1b is a node_vtable, valuedescr=i1 - ''') + ''', rop.GUARD_NO_EXCEPTION) def test_vref_virtual_after_finish(self): self.make_fail_descr() Modified: pypy/branch/guard-value-counting/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/guard-value-counting/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/guard-value-counting/pypy/module/pypyjit/interp_jit.py Fri Mar 5 13:43:12 2010 @@ -22,8 +22,6 @@ 'lastblock', ] -JUMP_ABSOLUTE = opmap['JUMP_ABSOLUTE'] - def can_inline(next_instr, bytecode): return not bool(bytecode.co_flags & CO_CONTAINSLOOP) @@ -49,14 +47,6 @@ greens = ['next_instr', 'pycode'] virtualizables = ['frame'] -## def compute_invariants(self, reds, next_instr, pycode): -## # compute the information that really only depends on next_instr -## # and pycode -## frame = reds.frame -## valuestackdepth = frame.valuestackdepth -## blockstack = frame.blockstack -## return (valuestackdepth, blockstack) - pypyjitdriver = PyPyJitDriver(can_inline = can_inline, get_printable_location = get_printable_location, get_jitcell_at = get_jitcell_at, From getxsick at codespeak.net Fri Mar 5 14:05:14 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 5 Mar 2010 14:05:14 +0100 (CET) Subject: [pypy-svn] r71796 - in pypy/build/ubuntu/debian: . manpages scripts Message-ID: <20100305130514.EA5C051055@codespeak.net> Author: getxsick Date: Fri Mar 5 14:05:13 2010 New Revision: 71796 Removed: pypy/build/ubuntu/debian/manpages/graphserver.1 pypy/build/ubuntu/debian/scripts/graphserver Modified: pypy/build/ubuntu/debian/pypy-dotviewer.install pypy/build/ubuntu/debian/pypy-dotviewer.manpages Log: remove graphserver from pypy-dotviewer Modified: pypy/build/ubuntu/debian/pypy-dotviewer.install ============================================================================== --- pypy/build/ubuntu/debian/pypy-dotviewer.install (original) +++ pypy/build/ubuntu/debian/pypy-dotviewer.install Fri Mar 5 14:05:13 2010 @@ -1,4 +1,3 @@ dotviewer usr/share/pypy-1.2 debian/scripts/dotviewer usr/bin -debian/scripts/graphserver usr/bin debian/scripts/sshgraphserver usr/bin Modified: pypy/build/ubuntu/debian/pypy-dotviewer.manpages ============================================================================== --- pypy/build/ubuntu/debian/pypy-dotviewer.manpages (original) +++ pypy/build/ubuntu/debian/pypy-dotviewer.manpages Fri Mar 5 14:05:13 2010 @@ -1,3 +1,2 @@ debian/manpages/dotviewer.1 -debian/manpages/graphserver.1 debian/manpages/sshgraphserver.1 From arigo at codespeak.net Fri Mar 5 15:12:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:12:48 +0100 (CET) Subject: [pypy-svn] r71798 - in pypy/release/1.2.x: . pypy/doc pypy/doc/jit pypy/doc/tool Message-ID: <20100305141248.0A14F51055@codespeak.net> Author: arigo Date: Fri Mar 5 15:12:41 2010 New Revision: 71798 Added: pypy/release/1.2.x/pypy/doc/release-1.2.0.txt - copied unchanged from r71659, pypy/trunk/pypy/doc/release-1.2.0.txt Modified: pypy/release/1.2.x/LICENSE pypy/release/1.2.x/pypy/doc/architecture.txt pypy/release/1.2.x/pypy/doc/contributor.txt pypy/release/1.2.x/pypy/doc/docindex.txt pypy/release/1.2.x/pypy/doc/download.txt pypy/release/1.2.x/pypy/doc/extradoc.txt pypy/release/1.2.x/pypy/doc/faq.txt pypy/release/1.2.x/pypy/doc/getting-started-dev.txt pypy/release/1.2.x/pypy/doc/getting-started-python.txt pypy/release/1.2.x/pypy/doc/getting-started.txt pypy/release/1.2.x/pypy/doc/how-to-release.txt pypy/release/1.2.x/pypy/doc/index.txt pypy/release/1.2.x/pypy/doc/jit/overview.txt pypy/release/1.2.x/pypy/doc/jit/pyjitpl5.txt pypy/release/1.2.x/pypy/doc/project-ideas.txt pypy/release/1.2.x/pypy/doc/tool/makecontributor.py pypy/release/1.2.x/pypy/doc/translation.txt Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71631:71659 Modified: pypy/release/1.2.x/LICENSE ============================================================================== --- pypy/release/1.2.x/LICENSE (original) +++ pypy/release/1.2.x/LICENSE Fri Mar 5 15:12:41 2010 @@ -35,18 +35,18 @@ copyrighted by one or more of the following people and organizations: Armin Rigo - Samuele Pedroni + Maciej Fijalkowski Carl Friedrich Bolz - Maciek Fijalkowski - Michael Hudson + Samuele Pedroni Antonio Cuni + Michael Hudson Christian Tismer Holger Krekel Eric van Riet Paap Richard Emslie Anders Chrigstrom - Aurelien Campeas Amaury Forgeot d Arc + Aurelien Campeas Anders Lehmann Niklaus Haldimann Seo Sanghyeon @@ -54,11 +54,12 @@ Lawrence Oluyede Jakub Gustak Guido Wesdorp - Niko Matsakis - Toon Verwaest + Benjamin Peterson Alexander Schremmer + Niko Matsakis Ludovic Aubry Alex Martelli + Toon Verwaest Stephan Diehl Adrien Di Mascio Stefan Schwarzer @@ -66,8 +67,8 @@ Patrick Maupin Jacob Hallen Laura Creighton - Camillo Bruni Bob Ippolito + Camillo Bruni Simon Burton Bruno Gola Alexandre Fayolle @@ -75,34 +76,35 @@ Guido van Rossum Valentino Volonghi Adrian Kuhn - Anders Hammarquist Paul deGrandis Gerald Klix Wanja Saatkamp + Anders Hammarquist Oscar Nierstrasz Eugene Oden Lukas Renggli - Bartosz SKOWRON Guenter Jantzen Dinu Gherman + Bartosz SKOWRON Georg Brandl - Benjamin Peterson Ben Young - Nicolas Chauvat Jean-Paul Calderone + Nicolas Chauvat Rocco Moretti Michael Twomey - Boris Feigin + boria Jared Grubb Olivier Dormond Stuart Williams Jens-Uwe Mager Justas Sadzevicius + Mikael Sch?nenberg Brian Dorsey Jonathan David Riehl Beatrice During Elmo M?ntynen Andreas Friedge + Alex Gaynor Anders Qvist Alan McIntyre Bert Freudenberg Modified: pypy/release/1.2.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/architecture.txt (original) +++ pypy/release/1.2.x/pypy/doc/architecture.txt Fri Mar 5 15:12:41 2010 @@ -250,7 +250,7 @@ .. _`Extreme Programming`: http://www.extremeprogramming.org/ .. _fast: faq.html#how-fast-is-pypy -.. _`very compliant`: http://codespeak.net:8099/summary?category=lib-python&branch=%3Ctrunk%3E +.. _`very compliant`: cpython_differences.html .. _`RPython`: coding-guide.html#rpython Modified: pypy/release/1.2.x/pypy/doc/contributor.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/contributor.txt (original) +++ pypy/release/1.2.x/pypy/doc/contributor.txt Fri Mar 5 15:12:41 2010 @@ -8,18 +8,18 @@ Armin Rigo - Samuele Pedroni + Maciej Fijalkowski Carl Friedrich Bolz - Maciek Fijalkowski - Michael Hudson + Samuele Pedroni Antonio Cuni + Michael Hudson Christian Tismer Holger Krekel Eric van Riet Paap Richard Emslie Anders Chrigstrom - Aurelien Campeas Amaury Forgeot d Arc + Aurelien Campeas Anders Lehmann Niklaus Haldimann Seo Sanghyeon @@ -27,11 +27,12 @@ Lawrence Oluyede Jakub Gustak Guido Wesdorp - Niko Matsakis - Toon Verwaest + Benjamin Peterson Alexander Schremmer + Niko Matsakis Ludovic Aubry Alex Martelli + Toon Verwaest Stephan Diehl Adrien Di Mascio Stefan Schwarzer @@ -39,8 +40,8 @@ Patrick Maupin Jacob Hallen Laura Creighton - Camillo Bruni Bob Ippolito + Camillo Bruni Simon Burton Bruno Gola Alexandre Fayolle @@ -48,46 +49,46 @@ Guido van Rossum Valentino Volonghi Adrian Kuhn - Anders Hammarquist Paul deGrandis Gerald Klix Wanja Saatkamp + Anders Hammarquist Oscar Nierstrasz Eugene Oden Lukas Renggli - Bartosz SKOWRON Guenter Jantzen Dinu Gherman + Bartosz SKOWRON Georg Brandl Ben Young - Nicolas Chauvat Jean-Paul Calderone + Nicolas Chauvat Rocco Moretti Michael Twomey - Boris Feigin + boria Jared Grubb Olivier Dormond Stuart Williams Jens-Uwe Mager Justas Sadzevicius + Mikael Sch?nenberg Brian Dorsey Jonathan David Riehl Beatrice During Elmo M?ntynen Andreas Friedge + Alex Gaynor Anders Qvist Alan McIntyre Bert Freudenberg Pieter Zieschang - Ignas Mikalajunas Jacob Oscarson Lutz Paelike - Benjamin Peterson Michael Schneider Artur Lisiecki Lene Wagner Christopher Armstrong - Joshua Gilbert + Jan de Mooij Jacek Generowicz Gasper Zejn Stephan Busemann @@ -95,11 +96,10 @@ Godefroid Chappelle Toby Watson Andrew Thompson - Gintautas Miliauskas + Joshua Gilbert Anders Sigfridsson - Neil Shepperd + David Schneider Michael Chermside tav - Igor Trindade Oliveira Martin Blais Victor Stinner Modified: pypy/release/1.2.x/pypy/doc/docindex.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/docindex.txt (original) +++ pypy/release/1.2.x/pypy/doc/docindex.txt Fri Mar 5 15:12:41 2010 @@ -73,9 +73,9 @@ Windows, on top of .NET, and on top of Java. To dig into PyPy it is recommended to try out the current Subversion HEAD, which is always working or mostly working, -instead of the `release 1.1.0`__. +instead of the latest release, which is `1.2.0`__. -.. __: release-1.1.0.html +.. __: release-1.2.0.html PyPy is mainly developed on Linux and Mac OS X. Windows is supported, but platform-specific bugs tend to take longer before we notice and fix Modified: pypy/release/1.2.x/pypy/doc/download.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/download.txt (original) +++ pypy/release/1.2.x/pypy/doc/download.txt Fri Mar 5 15:12:41 2010 @@ -2,19 +2,28 @@ Download one of the following release files: ============================================= -PyPy 1.1 Sources: +PyPy 1.2 Sources: ----------------- -* `pypy-1.1.0.tar.bz2`_ (sources, unix line endings) or -* `pypy-1.1.0.tar.gz`_ (sources, unix line endings) or -* `pypy-1.1.0.zip`_ (sources, windows line-endings) - -.. _`pypy-1.1.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.1.0.tar.bz2 -.. _`pypy-1.1.0.zip`: http://codespeak.net/download/pypy/pypy-1.1.0.zip -.. _`pypy-1.1.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.1.0.tar.gz +* `pypy-1.2.0.tar.bz2`_ (sources, unix line endings) or +* `pypy-1.2.0.tar.gz`_ (sources, unix line endings) or +* `pypy-1.2.0.zip`_ (sources, windows line-endings) + +.. _`pypy-1.2.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.bz2 +.. _`pypy-1.2.0.zip`: http://codespeak.net/download/pypy/pypy-1.2.0.zip +.. _`pypy-1.2.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.gz Prebuilt binaries ~~~~~~~~~~~~~~~~~ -We do not provide prebuilt binaries yet (but would happily -link to other people's pages with one version or another). +XXX + +The ``lang`` repository +~~~~~~~~~~~~~~~~~~~~~~~ + +The ``lang`` part of our repository, which contains other interpreters +developped mostly as external contributions, has moved and is no longer +included in the above packages. You can grab it by `browsing the +Subversion source`__. + +.. __: http://codespeak.net/svn/pypy/lang/ Modified: pypy/release/1.2.x/pypy/doc/extradoc.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/extradoc.txt (original) +++ pypy/release/1.2.x/pypy/doc/extradoc.txt Fri Mar 5 15:12:41 2010 @@ -7,6 +7,9 @@ *Articles about PyPy published so far, most recent first:* (bibtex_ file) +* `High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages`_, + A. Cuni, Ph.D. thesis + * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`_, C.F. Bolz, A. Cuni, M. Fijalkowski, A. Rigo @@ -55,6 +58,7 @@ .. _bibtex: http://codespeak.net/svn/pypy/extradoc/talk/bibtex.bib +.. _`High performance implementation of Python for CLI/.NET with JIT compiler generation for dynamic languages`: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf .. _`How to *not* write Virtual Machines for Dynamic Languages`: http://codespeak.net/svn/pypy/extradoc/talk/dyla2007/dyla.pdf .. _`Tracing the Meta-Level: PyPy's Tracing JIT Compiler`: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit.pdf .. _`Faster than C#: Efficient Implementation of Dynamic Languages on .NET`: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009-dotnet/cli-jit.pdf @@ -72,9 +76,17 @@ Talks and Presentations ---------------------------------- +Talks in 2010 ++++++++++++++ + +* `PyCon 2010`_. + + Talks in 2009 +++++++++++++ +* `RuPy 2009`_. + * `EuroPython talks 2009`_. * `PyCon talks 2009`_. @@ -227,6 +239,8 @@ * `Architecture introduction slides`_ a mostly up-to-date introduction for the Amsterdam PyPy-Sprint Dec 2003. +.. _`PyCon 2010`: http://morepypy.blogspot.com/2010/02/pycon-2010-report.html +.. _`RuPy 2009`: http://morepypy.blogspot.com/2009/11/pypy-on-rupy-2009.html .. _`PyPy 3000`: http://codespeak.net/pypy/extradoc/talk/ep2006/pypy3000.txt .. _`What can PyPy do for you`: http://codespeak.net/pypy/extradoc/talk/ep2006/usecases-slides.html .. _`PyPy introduction at EuroPython 2006`: http://codespeak.net/pypy/extradoc/talk/ep2006/intro.pdf Modified: pypy/release/1.2.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/faq.txt (original) +++ pypy/release/1.2.x/pypy/doc/faq.txt Fri Mar 5 15:12:41 2010 @@ -56,10 +56,12 @@ OS X and mostly works under Windows too (but is tested there less extensively). PyPy needs a CPython running on the target platform to bootstrap, as cross compilation is not really meant to work yet. -At the moment you need CPython 2.4 (with ctypes 0.9.9.6 or newer) or -CPython 2.5 for the translation process. +At the moment you need CPython 2.4 (with ctypes) or CPython 2.5 or 2.6 +for the translation process. -PyPy also basically works in a 64-bit Linux environment. +PyPy also basically works in a 64-bit Linux environment, but +*it requires a 32-bit Intel CPU* for the JIT right now. (It works +fine in a 32-bit chroot of an Intel 64.) ------------------------------------------------ Which Python version (2.x?) does PyPy implement? @@ -131,19 +133,25 @@ .. _whysoslow: -The answer to this question depends on how the PyPy interpreter is run. When -optimized and translated to C, the PyPy interpreter runs somewhere between 1 -and 2 times slower than CPython. If the PyPy interpreter is run on top of -CPython, i.e., without translation of any kind, then it is slower by a factor -of 2000. Obtaining good measurements for the performance when run on the CLI or -JVM is difficult, but it is safe to say that PyPy currently runs slower than -IronPython (CLI) or Jython (JVM) for most tests. - -The work on the Just-In-Time compiler is currently at its fifth revision, -but it looks like this revision is finally going to make it. It is work -in progress; see the `JIT documentation`_. +In three words, PyPy is "kind of fast". In more than three +words, the answer to this question is hard to give as a single +number. The fastest PyPy available so far is clearly PyPy +`with a JIT included`_, optimized and translated to C. This +version of PyPy is "kind of fast" in the sense that there are +numerous examples of Python code that run *much faster* than +CPython, up to a large number of times faster. And there are +also examples of code that are just as slow as without the +JIT. A PyPy that does not include a JIT has performance that +is more predictable: it runs generally somewhere between 1 and +2 times slower than CPython, in the worst case up to 4 times +slower. + +Obtaining good measurements for the performance when run on +the CLI or JVM is difficult, but the JIT on the CLI `seems to +work nicely`__ too. -.. _`JIT documentation`: jit/index.html +.. __: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf +.. _`with a JIT included`: jit/index.html .. _`prolog and javascript`: @@ -163,10 +171,11 @@ Currently, we have preliminary versions of a JavaScript interpreter (Leonardo Santagada as his Summer of PyPy project), a `Prolog interpreter`_ (Carl Friedrich Bolz as his Bachelor thesis), and a `SmallTalk interpreter`_ -(produced during a sprint). All of them are unfinished at the moment. +(produced during a sprint). `All of them`_ are unfinished at the moment. .. _`Prolog interpreter`: http://codespeak.net/svn/pypy/lang/prolog/ .. _`SmallTalk interpreter`: http://dx.doi.org/10.1007/978-3-540-89275-5_7 +.. _`All of them`: http://codespeak.net/svn/pypy/lang/ Development ======================================================================== Modified: pypy/release/1.2.x/pypy/doc/getting-started-dev.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/getting-started-dev.txt (original) +++ pypy/release/1.2.x/pypy/doc/getting-started-dev.txt Fri Mar 5 15:12:41 2010 @@ -334,7 +334,7 @@ ++++++++++++++++++++++++++++ `ctypes`_ is included in CPython 2.5 and higher. CPython 2.4 users needs to -install it (version 0.9.9.6 or later) if they want to run low-level tests. See +install it if they want to run low-level tests. See the `download page of ctypes`_. .. _`download page of ctypes`: http://sourceforge.net/project/showfiles.php?group_id=71702 Modified: pypy/release/1.2.x/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/getting-started-python.txt (original) +++ pypy/release/1.2.x/pypy/doc/getting-started-python.txt Fri Mar 5 15:12:41 2010 @@ -47,34 +47,28 @@ * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) * ``libexpat1-dev`` (for the optional ``pyexpat`` module) * ``libssl-dev`` (for the optional ``_ssl`` module) - * ``libgc-dev`` (only when translating with `--opt=0, 1` or `size`) + * ``libgc-dev`` (Boehm: only when translating with `--opt=0, 1` or `size`) 2. Translation is somewhat time-consuming (30 min to over one hour) and RAM-hungry. If you have less than 1.5 GB of RAM (or a slow machine) you might want to pick the `optimization level`_ `1` in the next step. A level of - `2` or `3` gives much better results, though. + `2` or `3` or `jit` gives much better results, though. Let me stress this another time: at ``--opt=1`` you get the Boehm GC, which is here mostly for historical and for testing reasons. You really do not want to pick it. The resulting ``pypy-c`` is slow. - Alternatively, if you want to enable the experimental JIT, choose - the optimization level ``jit``. - 3. Run:: cd pypy/translator/goal - python translate.py --opt=3 targetpypystandalone.py - - possibly replacing ``--opt=3`` with ``--opt=jit`` or another - `optimization level`_ of your choice. + python translate.py --opt=jit targetpypystandalone.py - On Linux 32-bit Intel machines, you can get some extra speed - (and extra translation time) by adding ``--gcrootfinder=asmgcc`` - just after the ``--opt`` option. (This option is implied by - ``--opt=jit``.) + possibly replacing ``--opt=jit`` with another `optimization level`_ + of your choice like ``--opt=2`` if you do not want the included JIT + compiler. (The default level so far is 2. Do not use ``--opt=jit`` + on something else than Intel **32-bit** machines.) .. _`optimization level`: config/opt.html @@ -99,11 +93,13 @@ >>>> This executable can be moved around or copied on other machines; see -Installation_ below. +Installation_ below. For now a JIT-enabled ``pypy-c`` always produces +debugging output to stderr when it exits, unless translated with +``--jit-debug=off``. The ``translate.py`` script takes a very large number of options controlling what to translate and how. See ``translate.py -h``. Some of the more -interesting options are: +interesting options (but for now incompatible with the JIT) are: * ``--stackless``: this produces a pypy-c that includes features inspired by `Stackless Python `__. @@ -121,54 +117,12 @@ .. _`translate PyPy with the thunk object space`: -Translating with the thunk object space +Translating with non-standard options ++++++++++++++++++++++++++++++++++++++++ -One of the original features provided by PyPy is the "thunk" -object space, providing lazily-computed objects in a fully -transparent manner:: - - cd pypy - python bin/py.py -o thunk - - >>>> from __pypy__ import thunk - >>>> def longcomputation(lst): - .... print "computing..." - .... return sum(lst) - .... - >>>> x = thunk(longcomputation, range(5)) - >>>> y = thunk(longcomputation, range(10)) - -From the application perspective, ``x`` and ``y`` represent -exactly the objects being returned by the ``longcomputation()`` -invocations. You can put these objects into a dictionary -without triggering the computation:: - - >>>> d = {5: x, 10: y} - >>>> result = d[5] - >>>> result - computing... - 10 - >>>> type(d[10]) - computing... - - >>>> d[10] - 45 - -It is interesting to note that this lazy-computing Python extension -is solely implemented in a small `objspace/thunk.py`_ file consisting -of around 200 lines of code. - -It is also possible to translate a PyPy version using the "thunk" object -space:: - - cd pypy/translator/goal - python translate.py targetpypystandalone.py --objspace=thunk - -the example above should work in the translated result. - -If you want know more about pypy-exclusive features go to `objspace proxies`_ -document. +It is possible to have non-standard features enabled for translation, +but they are not really tested any more. Look for example at the +`objspace proxies`_ document. .. _`objspace proxies`: objspace-proxies.html @@ -181,7 +135,15 @@ ./translate.py --backend=cli targetpypystandalone.py -The executable and all its dependecies will be stored in the +Or better, try out the experimental `branch/cli-jit`_ described by +Antonio Cuni's `Ph.D. thesis`_ and translate with the JIT:: + + ./translate.py -Ojit --backend=cli targetpypystandalone.py + +.. _`branch/cli-jit`: http://codespeak.net/svn/pypy/branch/cli-jit/ +.. _`Ph.D. thesis`: http://codespeak.net/svn/user/antocuni/phd/thesis/thesis.pdf + +The executable and all its dependencies will be stored in the ./pypy-cli-data directory. To run pypy.NET, you can run ./pypy-cli-data/main.exe. If you are using Linux or Mac, you can use the convenience ./pypy-cli script:: @@ -251,11 +213,11 @@ ``PREFIX/pypy/lib`` can all be found. The prefixes that are tried are:: . - ./share/pypy-1.1 + ./share/pypy-1.2 .. - ../share/pypy-1.1 + ../share/pypy-1.2 ../.. - ../../share/pypy-1.1 + ../../share/pypy-1.2 ../../.. etc. @@ -334,11 +296,6 @@ .. _`CLI backend`: cli-backend.html .. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ .. _clr: clr-module.html -.. _`CPythons core language regression tests`: http://codespeak.net:8099/summary?category=lib-python&branch=%3Ctrunk%3E +.. _`CPythons core language regression tests`: http://codespeak.net:8099/summary?category=applevel&branch=%3Ctrunk%3E .. include:: _ref.txt - - - - - Modified: pypy/release/1.2.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/getting-started.txt (original) +++ pypy/release/1.2.x/pypy/doc/getting-started.txt Fri Mar 5 15:12:41 2010 @@ -14,10 +14,9 @@ Python itself, flexible and easy to experiment with. We target a large variety of platforms, small and large, by providing a compiler toolsuite that can produce custom Python versions. Platform, memory -and threading models are aspects of the translation process - as -opposed to encoding low level details into the language implementation itself. -Eventually, dynamic optimization techniques - implemented as another -translation aspect - should become robust against language changes. `more...`_ +and threading models, as well as the JIT compiler itself, are aspects of the +translation process - as opposed to encoding low level details into the +language implementation itself. `more...`_ .. _Python: http://docs.python.org/ref .. _`more...`: architecture.html Modified: pypy/release/1.2.x/pypy/doc/how-to-release.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/how-to-release.txt (original) +++ pypy/release/1.2.x/pypy/doc/how-to-release.txt Fri Mar 5 15:12:41 2010 @@ -23,14 +23,14 @@ some of the next updates may be done before or after branching; make sure things are ported back to the trunk and to the branch as necessary -* update dist/pypy/doc/contributor.txt (and possibly dist/LICENSE) -* update dist/README -* write release announcement dist/pypy/doc/release-x.y(.z).txt +* update pypy/doc/contributor.txt (and possibly LICENSE) +* update README +* write release announcement pypy/doc/release-x.y(.z).txt the release announcement should contain a direct link to the download page (which is getting started). -* update dist/pypy/doc/getting-started.txt links at the top +* update pypy/doc/getting-started.txt links at the top and release number references, make sure it is generally up-to-date -* use, after the necessary updates, dist/pypy/tool/makerelease.py to +* use, after the necessary updates, pypy/tool/makerelease.py to make the tarballs on codespeak; this generates html doc for the tarballs too. Use:: @@ -44,6 +44,8 @@ if some stuff is missing. We have some support for running part of our nightly tests on tarballs (see http://codespeak.net/svn/user/pedronis/tarball-testing). -* write a news item for the release in dist/pypy/doc/news.txt +* write a news item for the release in pypy/doc/news.txt +* update http://codespeak.net/svn/pypy/dist and codespeak's + precomputed html files * send announcements to pypy-dev, pypy-funding, python-list, python-announce, python-dev ... Modified: pypy/release/1.2.x/pypy/doc/index.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/index.txt (original) +++ pypy/release/1.2.x/pypy/doc/index.txt Fri Mar 5 15:12:41 2010 @@ -8,7 +8,7 @@ Getting into PyPy ... ============================================= -* `Release 1.1`_: the latest official release +* `Release 1.2`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -56,4 +56,4 @@ .. _`Documentation`: docindex.html .. _`Getting Started`: getting-started.html .. _papers: extradoc.html -.. _`Release 1.1`: release-1.1.0.html +.. _`Release 1.2`: release-1.2.0.html Modified: pypy/release/1.2.x/pypy/doc/jit/overview.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/jit/overview.txt (original) +++ pypy/release/1.2.x/pypy/doc/jit/overview.txt Fri Mar 5 15:12:41 2010 @@ -16,23 +16,30 @@ -------- Writing an interpreter for a complex dynamic language like Python is not -a small task. So doing it a high-level language looks like a good idea, -because high-level languages have many advantages over low-level ones -(flexibility, ease of implementation, no low-level issues...). This is -the basic observation behind PyPy. - -But coding in a high-level language has other benefits beyond the -obvious ones. Perhaps most importantly, it allows the language -interpreter to be analyzed when turned into a compiler. This is -precisely what our JIT compiler generator does. Based on tracing -JIT techniques, **it can turn the interpreter of an arbitrary -dynamic language into a just-in-time compiler for the same language.** -It works mostly automatically and only needs guidance by the language -implementor in the form of a small number of hints in the source code of -the interpreter. The resulting JIT compiler has the same language -semantics as the original interpreter by construction. It generates -machine code for the user program while aggressively optimizing it, -leading to a big performance boost. +a small task, especially if, for performance goals, we want to write a +Just-in-Time (JIT) compiler too. + +The good news is that it's not what we did. We indeed wrote an +interpreter for Python, but we never wrote any JIT compiler for Python +in PyPy. Instead, we use the fact that our interpreter for Python is +written in RPython, which is a nice, high-level language -- and we turn +it *automatically* into a JIT compiler for Python. + +This transformation is of course completely transparent to the user, +i.e. the programmer writing Python programs. The goal (which we +achieved) is to support *all* Python features -- including, for example, +random frame access and debuggers. But it is also mostly transparent to +the language implementor, i.e. to the source code of the Python +interpreter. It only needs a bit of guidance: we had to put a small +number of hints in the source code of our interpreter. Based on these +hints, the *JIT compiler generator* produces a JIT compiler which has +the same language semantics as the original interpreter by construction. +This JIT compiler itself generates machine code at runtime, aggressively +optimizing the user's program and leading to a big performance boost, +while keeping the semantics unmodified. Of course, the interesting bit +is that our Python language interpreter can evolve over time without +getting out of sync with the JIT compiler. + The path we followed -------------------- @@ -47,13 +54,15 @@ compilers. If this turns out to be correct, the practical speed of dynamic languages could be vastly improved. -Today (beginning 2009), our prototype is no longer using partial -evaluation -- at least not in a way that would convince paper reviewers. -It is instead based on the notion of *tracing JIT,* recently studied for -Java and JavaScript. When compared to all existing tracing JITs so far, -however, partial evaluation gives us some extra techniques that we -already had in our previous JIT generators, notably how to optimize -structures by removing allocations. +All these previous JIT compiler generators were producing JIT compilers +similar to the hand-written Psyco. But today, starting from 2009, our +prototype is no longer using partial evaluation -- at least not in a way +that would convince paper reviewers. It is instead based on the notion +of *tracing JIT,* recently studied for Java and JavaScript. When +compared to all existing tracing JITs so far, however, partial +evaluation gives us some extra techniques that we already had in our +previous JIT generators, notably how to optimize structures by removing +allocations. The closest comparison to our current JIT is Tamarin's TraceMonkey. However, this JIT compiler is written manually, which is quite some @@ -87,12 +96,8 @@ is modified, so that they cannot get out of sync no matter how fast the language evolves. -* Fast enough: we think that we can get some rather good performance out - of the generated JIT compilers. That's the whole point, of course. - Previous experience shows that it should be possible. Our previous - generated JIT compilers were similar to the hand-written Psyco; due - to limits in automating the way Psyco works, our current generated - JIT compilers are instead similar to tracing JITs like TraceMonkey. +* Fast enough: we can get some rather good performance out of the + generated JIT compilers. That's the whole point, of course. Alternative approaches to improve speed Modified: pypy/release/1.2.x/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/release/1.2.x/pypy/doc/jit/pyjitpl5.txt Fri Mar 5 15:12:41 2010 @@ -172,7 +172,7 @@ * `Tracing the Meta-Level: PyPy's Tracing JIT Compiler`__ -.. __: http://codespeak.net/svn/pypy/extradoc/talk/ipcoolps2009/bolz-tracing-jit.pdf +.. __: http://codespeak.net/svn/pypy/extradoc/talk/icooolps2009/bolz-tracing-jit-final.pdf as well as the `blog posts with the JIT tag.`__ Modified: pypy/release/1.2.x/pypy/doc/project-ideas.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/project-ideas.txt (original) +++ pypy/release/1.2.x/pypy/doc/project-ideas.txt Fri Mar 5 15:12:41 2010 @@ -1,8 +1,6 @@ Independent project ideas relating to PyPy ========================================== -*NOTE: This is an extremely outdated list, don't consider it seriously* - PyPy allows experimentation in many directions -- indeed facilitating experimentation in language implementation was one of the main motivations for the project. This page is meant to collect some ideas @@ -23,35 +21,41 @@ -------------------------------- PyPy's Just-In-Time compiler relies on backends for actual code -generation. Right now we are working on the ``pyjitpl5`` branch, which -is not stable. Working on the JIT backends should be soon possible. -Open ideas are to write a backend for AMD64 (Intel 64); or .NET or -Java (requires porting the JIT frontend to ootype too, which is not too -hard); or trying to use LLVM-JIT. +generation. We have so far a 32-bit Intel backend, and a CLI one. Open +ideas are to write a backend for **Intel 64** (AMD64); or a backend for +Java; or trying again to use LLVM-JIT (which I do not really recommend). CTypes ------ Support ctypes on more backends. Right now ctypes is supported only -when compiling PyPy to C. A nice project would be to support it when +when compiling PyPy to C, and there is a bit of unfinished work to +support it on **Intel 64.** A nice project would be to support it when compiling to .NET or the JVM. That's not too hard, the only thing needed is to port a small module that does the actual invocation of external -libraries (a related project would be to port this module to Jython or -IronPython to get support for ctypes there). +libraries (a related project is to port this module to Jython or +IronPython to get support for ctypes there, which is something that was +tried but not finished as far as I know). .. _distribution: .. _persistence: -Experiment with distribution and persistence --------------------------------------------- +Extensions of the Python language +--------------------------------- + ++----------------------------------------------------------------------+ +| :NOTE: | +| | +| The ideas in this paragraph are marked as "experimental". We may | +| or may not be interested in helping you out. You are warned :-) | +| | ++----------------------------------------------------------------------+ One of the advantages of PyPy's implementation is that the Python-level type of an object and its implementation are completely independent. This should allow a much more intuitive interface to, for example, objects that are backed -by a persistent store. - -The `transparent proxy`_ objects are a key step in this +by a persistent store. The `transparent proxy`_ objects are a key step in this direction; now all that remains is to implement the interesting bits :-) An example project might be to implement functionality akin to the `ZODB's @@ -61,15 +65,22 @@ Another example would be to implement a multi-CPU extension that internally uses several processes and uses transparent proxies to share object views. +Other ideas are to do something interesting with sandboxing_; or to +work more on the Stackless_ features (e.g. integrate it with the JIT); +or revive the logic object space, which tried to bring unification-like +features to Python. + +.. _sandboxing: sandbox.html +.. _Stackless: stackless.html + -Various Ideas -------------- +Other languages +--------------- -- improve one of the existing interpreters (e.g. the Prolog, the Scheme or - the JavaScript interpreter or the Smalltalk VM), or start a new one +Improve one of the `existing interpreters`__, or start a new one. +Experiment with the JIT compiler generator. -- revive the logic object space, which tried to bring unification-like - features to Python +.. __: http://codespeak.net/svn/pypy/lang/ Or else... Modified: pypy/release/1.2.x/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/release/1.2.x/pypy/doc/tool/makecontributor.py (original) +++ pypy/release/1.2.x/pypy/doc/tool/makecontributor.py Fri Mar 5 15:12:41 2010 @@ -8,12 +8,12 @@ try: path = py.std.sys.argv[1] except IndexError: - print "usage: %s PATH" %(py.std.sys.argv[0]) + print "usage: %s ROOTPATH" %(py.std.sys.argv[0]) raise SystemExit, 1 d = {} -for logentry in py.path.svnwc(py.std.sys.argv[1]).log(): +for logentry in py.path.svnwc(path).log(): a = logentry.author if a in d: d[a] += 1 @@ -30,6 +30,8 @@ cutoff = 5 # cutoff for authors in the LICENSE file mark = False for author, count in items: + if author in excluded: + continue user = uconf.system.User(author) try: realname = user.realname.strip() Modified: pypy/release/1.2.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/translation.txt (original) +++ pypy/release/1.2.x/pypy/doc/translation.txt Fri Mar 5 15:12:41 2010 @@ -27,7 +27,7 @@ this task into several steps, and the purpose of this document is to introduce them. -As of the 1.1 release, RPython_ programs can be translated into the following +As of the 1.2 release, RPython_ programs can be translated into the following languages/platforms: C/POSIX, CLI/.NET and Java/JVM (in addition, there's `a backend`_ that translates `application-level`_ into `interpreter-level`_ code, but this is a special From arigo at codespeak.net Fri Mar 5 15:14:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:14:33 +0100 (CET) Subject: [pypy-svn] r71799 - in pypy/release/1.2.x/pypy: doc translator/c/test translator/jvm/test translator/platform Message-ID: <20100305141433.55C1051055@codespeak.net> Author: arigo Date: Fri Mar 5 15:14:31 2010 New Revision: 71799 Modified: pypy/release/1.2.x/pypy/doc/getting-started-python.txt pypy/release/1.2.x/pypy/translator/c/test/test_standalone.py pypy/release/1.2.x/pypy/translator/jvm/test/test_builtin.py pypy/release/1.2.x/pypy/translator/platform/maemo.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71702:71707 Modified: pypy/release/1.2.x/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/getting-started-python.txt (original) +++ pypy/release/1.2.x/pypy/doc/getting-started-python.txt Fri Mar 5 15:14:31 2010 @@ -67,8 +67,8 @@ possibly replacing ``--opt=jit`` with another `optimization level`_ of your choice like ``--opt=2`` if you do not want the included JIT - compiler. (The default level so far is 2. Do not use ``--opt=jit`` - on something else than Intel **32-bit** machines.) + compiler. (As of March 2010, the default level is ``--opt=2``, and + ``--opt=jit`` requires an Intel **32-bit** environment.) .. _`optimization level`: config/opt.html Modified: pypy/release/1.2.x/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/c/test/test_standalone.py (original) +++ pypy/release/1.2.x/pypy/translator/c/test/test_standalone.py Fri Mar 5 15:14:31 2010 @@ -398,7 +398,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: ValueError' + idx = lines.index('Fatal RPython error: ValueError') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' @@ -408,7 +409,8 @@ out2, err2 = cbuilder.cmdexec("x", expect_crash=True) assert out2.strip() == '' lines2 = err2.strip().splitlines() - assert lines2[-1] == 'Fatal RPython error: KeyError' + idx = lines2.index('Fatal RPython error: KeyError') # assert found + lines2 = lines2[:idx+1] l0, l1, l2 = lines2[-4:-1] assert l0 == 'RPython traceback:' assert re.match(r' File "\w+.c", line \d+, in entry_point', l1) @@ -435,7 +437,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == 'done.' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: KeyError' + idx = lines.index('Fatal RPython error: KeyError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -471,7 +474,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == 'done.' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: KeyError' + idx = lines.index('Fatal RPython error: KeyError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -506,7 +510,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: ValueError' + idx = lines.index('Fatal RPython error: ValueError') # assert found + lines = lines[:idx+1] assert len(lines) >= 5 l0, l1, l2, l3 = lines[-5:-1] assert l0 == 'RPython traceback:' @@ -522,7 +527,7 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'in pypy_g_RPyRaiseException: AssertionError' + assert 'in pypy_g_RPyRaiseException: AssertionError' in lines def test_assertion_error_nondebug(self): def g(x): @@ -539,7 +544,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'Fatal RPython error: AssertionError' + idx = lines.index('Fatal RPython error: AssertionError') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' @@ -556,7 +562,7 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'in pypy_g_entry_point: foobar' + assert 'in pypy_g_entry_point: foobar' in lines def test_ll_assert_error_nondebug(self): py.test.skip("implement later, maybe: tracebacks even with ll_assert") @@ -574,7 +580,8 @@ out, err = cbuilder.cmdexec("", expect_crash=True) assert out.strip() == '' lines = err.strip().splitlines() - assert lines[-1] == 'PyPy assertion failed: foobar' + idx = lines.index('PyPy assertion failed: foobar') # assert found + lines = lines[:idx+1] assert len(lines) >= 4 l0, l1, l2 = lines[-4:-1] assert l0 == 'RPython traceback:' Modified: pypy/release/1.2.x/pypy/translator/jvm/test/test_builtin.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/jvm/test/test_builtin.py (original) +++ pypy/release/1.2.x/pypy/translator/jvm/test/test_builtin.py Fri Mar 5 15:14:31 2010 @@ -29,7 +29,7 @@ def test_os_access(self): from socket import gethostname - if gethostname() == 'wyvern': + if 1: # gethostname() == 'wyvern': py.test.skip('bug in JDK when run headless: ' + 'http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705') BaseTestBuiltin.test_os_access(self) Modified: pypy/release/1.2.x/pypy/translator/platform/maemo.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/platform/maemo.py (original) +++ pypy/release/1.2.x/pypy/translator/platform/maemo.py Fri Mar 5 15:14:31 2010 @@ -1,11 +1,12 @@ -import py +import py, os 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(): + # in order to work, that file must exist and be executable by us + if not os.access('/scratchbox/login', os.X_OK): py.test.skip("No scratchbox detected") class Maemo(Linux): From arigo at codespeak.net Fri Mar 5 15:15:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:15:58 +0100 (CET) Subject: [pypy-svn] r71800 - in pypy/release/1.2.x: . pypy/doc Message-ID: <20100305141558.BB97E51055@codespeak.net> Author: arigo Date: Fri Mar 5 15:15:57 2010 New Revision: 71800 Modified: pypy/release/1.2.x/LICENSE pypy/release/1.2.x/pypy/doc/contributor.txt Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71767:71768 Modified: pypy/release/1.2.x/LICENSE ============================================================================== --- pypy/release/1.2.x/LICENSE (original) +++ pypy/release/1.2.x/LICENSE Fri Mar 5 15:15:57 2010 @@ -85,7 +85,7 @@ Lukas Renggli Guenter Jantzen Dinu Gherman - Bartosz SKOWRON + Bartosz Skowron Georg Brandl Ben Young Jean-Paul Calderone Modified: pypy/release/1.2.x/pypy/doc/contributor.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/contributor.txt (original) +++ pypy/release/1.2.x/pypy/doc/contributor.txt Fri Mar 5 15:15:57 2010 @@ -58,7 +58,7 @@ Lukas Renggli Guenter Jantzen Dinu Gherman - Bartosz SKOWRON + Bartosz Skowron Georg Brandl Ben Young Jean-Paul Calderone From arigo at codespeak.net Fri Mar 5 15:16:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:16:51 +0100 (CET) Subject: [pypy-svn] r71801 - in pypy/release/1.2.x/pypy/config: . test Message-ID: <20100305141651.8B01551055@codespeak.net> Author: arigo Date: Fri Mar 5 15:16:49 2010 New Revision: 71801 Modified: pypy/release/1.2.x/pypy/config/pypyoption.py pypy/release/1.2.x/pypy/config/test/test_pypyoption.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71789:71790 Modified: pypy/release/1.2.x/pypy/config/pypyoption.py ============================================================================== --- pypy/release/1.2.x/pypy/config/pypyoption.py (original) +++ pypy/release/1.2.x/pypy/config/pypyoption.py Fri Mar 5 15:16:49 2010 @@ -325,7 +325,6 @@ config.objspace.opcodes.suggest(CALL_LIKELY_BUILTIN=True) if level in ['2', '3', 'jit']: config.objspace.opcodes.suggest(CALL_METHOD=True) - config.objspace.std.suggest(withshadowtracking=True) config.objspace.std.suggest(withrangelist=True) config.objspace.std.suggest(withmethodcache=True) config.objspace.std.suggest(withprebuiltchar=True) Modified: pypy/release/1.2.x/pypy/config/test/test_pypyoption.py ============================================================================== --- pypy/release/1.2.x/pypy/config/test/test_pypyoption.py (original) +++ pypy/release/1.2.x/pypy/config/test/test_pypyoption.py Fri Mar 5 15:16:49 2010 @@ -47,7 +47,7 @@ def test_set_pypy_opt_level(): conf = get_pypy_config() set_pypy_opt_level(conf, '2') - assert conf.objspace.std.withshadowtracking + assert conf.objspace.std.withsharingdict conf = get_pypy_config() set_pypy_opt_level(conf, '0') assert not conf.objspace.std.newshortcut From arigo at codespeak.net Fri Mar 5 15:29:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:29:13 +0100 (CET) Subject: [pypy-svn] r71802 - pypy/trunk/pypy/translator/platform Message-ID: <20100305142913.59B4051055@codespeak.net> Author: arigo Date: Fri Mar 5 15:29:11 2010 New Revision: 71802 Modified: pypy/trunk/pypy/translator/platform/__init__.py Log: Fix this. 'Darwin' is not even imported. Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Fri Mar 5 15:29:11 2010 @@ -181,13 +181,11 @@ elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64 import platform - if platform.machine() == 'i386': - if sys.maxint <= 2147483647: - host_factory = Darwin_i386 - else: - host_factory = Darwin_x86_64 + assert platform.machine() in ('i386', 'x86_64') + if sys.maxint <= 2147483647: + host_factory = Darwin_i386 else: - host_factory = Darwin + host_factory = Darwin_x86_64 elif sys.platform == 'freebsd7': from pypy.translator.platform.freebsd7 import Freebsd7, Freebsd7_64 import platform From arigo at codespeak.net Fri Mar 5 15:29:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 15:29:53 +0100 (CET) Subject: [pypy-svn] r71803 - pypy/release/1.2.x/pypy/translator/platform Message-ID: <20100305142953.B6F5051055@codespeak.net> Author: arigo Date: Fri Mar 5 15:29:52 2010 New Revision: 71803 Modified: pypy/release/1.2.x/pypy/translator/platform/__init__.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71801:71802 Modified: pypy/release/1.2.x/pypy/translator/platform/__init__.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/platform/__init__.py (original) +++ pypy/release/1.2.x/pypy/translator/platform/__init__.py Fri Mar 5 15:29:52 2010 @@ -181,13 +181,11 @@ elif sys.platform == 'darwin': from pypy.translator.platform.darwin import Darwin_i386, Darwin_x86_64 import platform - if platform.machine() == 'i386': - if sys.maxint <= 2147483647: - host_factory = Darwin_i386 - else: - host_factory = Darwin_x86_64 + assert platform.machine() in ('i386', 'x86_64') + if sys.maxint <= 2147483647: + host_factory = Darwin_i386 else: - host_factory = Darwin + host_factory = Darwin_x86_64 elif sys.platform == 'freebsd7': from pypy.translator.platform.freebsd7 import Freebsd7, Freebsd7_64 import platform From tobami at codespeak.net Fri Mar 5 16:30:26 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Fri, 5 Mar 2010 16:30:26 +0100 (CET) Subject: [pypy-svn] r71805 - in codespeed/pyspeed: codespeed templates Message-ID: <20100305153026.7BDA351055@codespeak.net> Author: tobami Date: Fri Mar 5 16:30:24 2010 New Revision: 71805 Modified: codespeed/pyspeed/codespeed/views.py codespeed/pyspeed/templates/overview.html codespeed/pyspeed/templates/overview_table.html codespeed/pyspeed/templates/timeline.html Log: changed permalinkToTimeline so that it selects both default interpreters. Changed arithmetic average implementation. Refactored a bit duplicated colortable and update table overview.html code Modified: codespeed/pyspeed/codespeed/views.py ============================================================================== --- codespeed/pyspeed/codespeed/views.py (original) +++ codespeed/pyspeed/codespeed/views.py Fri Mar 5 16:30:24 2010 @@ -146,6 +146,7 @@ ).filter(interpreter=1) table_list = [] + totals = {'change': [], 'trend': [], 'relative': []} for bench in Benchmark.objects.all(): resultquery = result_list.filter(benchmark=bench) if not len(resultquery): continue @@ -155,6 +156,7 @@ c = change_list.filter(benchmark=bench) if c.count(): change = (result - c[0].value)*100/c[0].value + totals['change'].append(result / c[0].value) #calculate past average average = 0 @@ -174,7 +176,7 @@ if average: average = average / averagecount trend = (result - average)*100/average - #trend = "%.2f" % trend + totals['trend'].append(result / average) else: trend = "-" @@ -182,6 +184,7 @@ c = base_list.filter(benchmark=bench) if c.count(): relative = c[0].value / result + totals['relative'].append(relative) table_list.append({ 'benchmark': bench.name, 'bench_description': bench.description, @@ -191,15 +194,23 @@ 'relative': relative }) - totals = {'result': 0, 'change': 0, 'trend': 0, 'relative': 0} - lengths = {'result': 0, 'change': 0, 'trend': 0, 'relative': 0} - for row in table_list: - for key in totals.keys(): - if type(row[key]) == float: - totals[key] += row[key] - lengths[key] += 1 - for tot in totals: - if lengths[tot]: totals[tot] = totals[tot]/lengths[tot] + # Compute Arithmetic averages + for key in totals.keys(): + totals[key] = float(sum(totals[key]) / len(totals[key])) + totals['change'] = (totals['change'] - 1) * 100#transform ratio to percentage + totals['trend'] = (totals['trend'] - 1) * 100#transform ratio to percentage + + # Compute Geometric average + #for key in totals: + #if not len(totals[key]): + #totals[key] = "-" + #continue + ## taken from python-statlib + #mult = 1.0 + #one_over_n = 1.0/len(totals[key]) + #for item in totals[key]: + #mult = mult * pow(item,one_over_n) + #totals[key] = mult - 1.0 return render_to_response('overview_table.html', locals()) Modified: codespeed/pyspeed/templates/overview.html ============================================================================== --- codespeed/pyspeed/templates/overview.html (original) +++ codespeed/pyspeed/templates/overview.html Fri Mar 5 16:30:24 2010 @@ -18,6 +18,11 @@ function permalinkToTimeline(benchmark) { var conf = new Object(); conf["interpreters"] = $("input[name='interpreter']:checked").val(); + //configure default interpreters checked (2 and 3) + //if interpreter is pypy-c or pypy-c-jit add the other one. + //If it is none of those keep just that one + if (conf["interpreters"] == "2") { conf["interpreters"] += ",3"; } + else if (conf["interpreters"] == "3") { conf["interpreters"] += ",2"; } conf["benchmark"] = benchmark; window.location="/timeline/?" + ued_encode(conf); } @@ -40,19 +45,7 @@ var changethres = {{ defaultchangethres }}; var trendthres = {{ defaulttrendthres }}; var compthres = {{ defaultcompthres }}; - $("#results > tbody > tr").each(function() { - //Color change column - var change = $(this).children("td:eq(2)").text().slice(0, -1); - $(this).children("td:eq(2)").addClass(getColorcode(-change, changethres, -changethres)); - //Color trend column - var trend = $(this).children("td:eq(3)").text().slice(0, -1); - $(this).children("td:eq(3)").addClass(getColorcode(-trend, trendthres, -trendthres)); - //Color comparison column - var comp = parseFloat($(this).children("td:eq(4)").text()); - $(this).children("td:eq(4)").addClass(getColorcode(comp, 1+compthres, 1-compthres)); - }); - //process average row - $("#results > tfoot > tr").each(function() { + $("#results > :not(thead) > tr").each(function() { //Color change column var change = $(this).children("td:eq(2)").text().slice(0, -1); $(this).children("td:eq(2)").addClass(getColorcode(-change, changethres, -changethres)); @@ -65,9 +58,9 @@ function updateTable() { colorTable(); //process table rows + var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); $("#results > tbody > tr").each(function() { //Size plot bars - var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); var bar = transToLogBars(58, tdwidth, parseFloat($(this).children("td:eq(4)").text())); $(this).children("td:eq(5)").find("span").css("width", bar["width"]).css("margin-left", bar["margin"]); //Link rows to timelines @@ -78,7 +71,6 @@ //process average row $("#results > tfoot > tr").each(function() { //Size plot bar for Average - var tdwidth = parseInt($("#results thead tr").find("th:eq(5)").css("width")); var bar = transToLogBars(58, tdwidth, parseFloat($(this).children("td:eq(4)").text())); $(this).children("td:eq(5)").find("span").css("width", bar["width"]).css("margin-left", bar["margin"]); }); Modified: codespeed/pyspeed/templates/overview_table.html ============================================================================== --- codespeed/pyspeed/templates/overview_table.html (original) +++ codespeed/pyspeed/templates/overview_table.html Fri Mar 5 16:30:24 2010 @@ -5,7 +5,7 @@ - Average{{ totals.change|floatformat:2 }}%{{ totals.trend|floatformat:2 }}%{{ totals.relative|floatformat:2 }}- + Average{{ totals.change|floatformat:2 }}%{{ totals.trend|floatformat:2 }}%{{ totals.relative|floatformat:2 }}- {% for row in table_list %} Modified: codespeed/pyspeed/templates/timeline.html ============================================================================== --- codespeed/pyspeed/templates/timeline.html (original) +++ codespeed/pyspeed/templates/timeline.html Fri Mar 5 16:30:24 2010 @@ -29,7 +29,7 @@ function renderPlot(data) { if(data["error"] != "None") { - h = parseInt($("#content").css("height")); + h = parseInt($("#content").css("height"));//get height for error message $("#content").html(getLoadText(data["error"], h)); return 1; } @@ -160,7 +160,7 @@
Results for last - {% for rev in lastrevisions %} {% endfor %} revisions
From fijal at codespeak.net Fri Mar 5 17:05:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 17:05:46 +0100 (CET) Subject: [pypy-svn] r71808 - pypy/benchmarks Message-ID: <20100305160546.C71A351057@codespeak.net> Author: fijal Date: Fri Mar 5 17:05:45 2010 New Revision: 71808 Modified: pypy/benchmarks/runner.py Log: Kill --fast for now. We should have better way to distinguish warmup from normal run, but for now simply kill fast Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Mar 5 17:05:45 2010 @@ -14,7 +14,7 @@ force_host=None): funcs = perf.BENCH_FUNCS.copy() funcs.update(perf._FindAllBenchmarks(benchmarks.__dict__)) - opts = ['-f', '-b', ','.join(benchmark_set), '--inherit_env=PATH', + opts = ['-b', ','.join(benchmark_set), '--inherit_env=PATH', '--no_charts'] if args: opts += ['--args', args] From fijal at codespeak.net Fri Mar 5 17:20:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 17:20:24 +0100 (CET) Subject: [pypy-svn] r71810 - in pypy/benchmarks: . own own/twisted unladen_swallow Message-ID: <20100305162024.9A2C551057@codespeak.net> Author: fijal Date: Fri Mar 5 17:20:22 2010 New Revision: 71810 Added: pypy/benchmarks/own/twisted/ pypy/benchmarks/own/twisted/TODO pypy/benchmarks/own/twisted/accepts.py (contents, props changed) pypy/benchmarks/own/twisted/all.py (contents, props changed) pypy/benchmarks/own/twisted/benchlib.py (contents, props changed) pypy/benchmarks/own/twisted/iteration.py (contents, props changed) pypy/benchmarks/own/twisted/names.py (contents, props changed) pypy/benchmarks/own/twisted/pb.py (contents, props changed) pypy/benchmarks/own/twisted/tcp.py (contents, props changed) pypy/benchmarks/own/twisted/threads.py (contents, props changed) pypy/benchmarks/own/twisted/web.py (contents, props changed) Removed: pypy/benchmarks/own/twisted_benchlib.py pypy/benchmarks/own/twisted_iteration.py pypy/benchmarks/own/twisted_names.py pypy/benchmarks/own/twisted_web.py Modified: pypy/benchmarks/benchmarks.py pypy/benchmarks/unladen_swallow/perf.py Log: Import twisted benchmarks from their official place. Kill our edited versions. By default we run 3 iterations of warmup + 10 iterations of normal, until we have a better metric, that's probably fine Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 5 17:20:22 2010 @@ -17,22 +17,34 @@ d[BM.func_name] = BM -TWISTED = [relative('lib/twisted-trunk'), relative('lib/zope.interface-3.5.3/src')] +def _register_new_bm_twisted(name, bm_name, d, **opts): + def Measure(python, options): + def parser(line): + number = float(line.split(" ")[0]) + return 3000/number + bm_path = relative('own', 'twisted', name + '.py') + return MeasureGeneric(python, options, bm_path, parser=parser, **opts) + Measure.func_name = 'Measure' + name.capitalize() + + def BM(*args, **kwds): + return SimpleBenchmark(Measure, *args, **kwds) + BM.func_name = 'BM_' + bm_name + + d[BM.func_name] = BM + +TWISTED = [relative('lib/twisted-trunk'), relative('lib/zope.interface-3.5.3/src'), relative('own/twisted')] opts = { 'gcbench' : {'iteration_scaling' : .10}, - 'twisted_iteration': {'iteration_scaling': .10, - 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}}, - 'twisted_web': {'iteration_scaling': .10, - 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}}, - 'twisted_names': {'iteration_scaling': .10, - 'bm_env': {'PYTHONPATH': ':'.join(TWISTED)}}, } for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', - 'spectral-norm', 'chaos', 'telco', 'gcbench', - 'twisted_iteration', 'twisted_web', 'twisted_names']: + 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, name, globals(), **opts.get(name, {})) +for name in ['web', 'names', 'accepts', 'iteration', 'tcp', 'pb']: + _register_new_bm_twisted(name, 'twisted_' + name, + globals(), bm_env={'PYTHONPATH': ':'.join(TWISTED)}, + iteration_scaling=.20) _register_new_bm('spitfire', 'spitfire', globals(), extra_args=['--benchmark=spitfire_o4']) _register_new_bm('spitfire', 'spitfire_cstringio', globals(), Added: pypy/benchmarks/own/twisted/TODO ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/TODO Fri Mar 5 17:20:22 2010 @@ -0,0 +1,2 @@ +Debug dns slowdown over time +Add an AMP benchmark Added: pypy/benchmarks/own/twisted/accepts.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/accepts.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,55 @@ + +from __future__ import division + +from twisted.internet.protocol import ServerFactory, ClientFactory, Protocol +from twisted.internet.error import ConnectionClosed +from twisted.internet.defer import Deferred + +from benchlib import Client, driver + + +class Client(Client): + def __init__(self, reactor, portNumber): + super(Client, self).__init__(reactor) + self._portNumber = portNumber + self._factory = ClientFactory() + + + def _request(self): + finished = Deferred() + factory = ClientFactory() + factory.protocol = Protocol + factory.clientConnectionLost = factory.clientConnectionFailed = lambda connector, reason: finished.errback(reason) + finished.addErrback(self._filterFinished) + self._reactor.connectTCP('127.0.0.1', self._portNumber, factory) + finished.addCallback(self._continue) + finished.addErrback(self._stop) + + + def _filterFinished(self, reason): + reason.trap(ConnectionClosed) + + +class CloseConnection(Protocol): + def makeConnection(self, transport): + transport.loseConnection() + + + +def main(reactor, duration): + concurrency = 50 + + factory = ServerFactory() + factory.protocol = CloseConnection + port = reactor.listenTCP(0, factory) + + client = Client(reactor, port.getHost().port) + d = client.run(concurrency, duration) + return d + + + +if __name__ == '__main__': + import sys + import accepts + driver(accepts.main, sys.argv) Added: pypy/benchmarks/own/twisted/all.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/all.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,8 @@ + +from benchlib import multidriver + +import accepts, tcp, iteration, names, threads, web, pb + +if __name__ == '__main__': + multidriver( + accepts.main, tcp.main, iteration.main, names.main, threads.main, web.main, pb.main) Added: pypy/benchmarks/own/twisted/benchlib.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/benchlib.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,87 @@ + +import sys +from twisted.internet.defer import Deferred +from twisted.internet import reactor +from twisted.python import log + +class Client(object): + def __init__(self, reactor): + self._reactor = reactor + self._requestCount = 0 + + def run(self, concurrency, duration): + self._reactor.callLater(duration, self._stop, None) + self._finished = Deferred() + for i in range(concurrency): + self._request() + return self._finished + + def _continue(self, ignored): + self._requestCount += 1 + if self._finished is not None: + self._request() + + def _stop(self, reason): + if self._finished is not None: + finished = self._finished + self._finished = None + if reason is not None: + finished.errback(reason) + else: + finished.callback(self._requestCount) + +PRINT_TEMPL = ('%(stats)s %(name)s/sec (%(count)s %(name)s ' + 'in %(duration)s seconds)') + +def benchmark_report(acceptCount, duration, name): + print PRINT_TEMPL % { + 'stats' : acceptCount / duration, + 'name' : name, + 'count' : acceptCount, + 'duration' : duration + } + +def setup_driver(f, argv, reactor): + from twisted.python.usage import Options + + class BenchmarkOptions(Options): + optParameters = [ + ('iterations', 'n', 1, 'number of iterations', int), + ('duration', 'd', 5, 'duration of each iteration', float), + ('warmup', 'w', 3, 'number of warmup iterations', int), + ] + + options = BenchmarkOptions() + options.parseOptions(argv[1:]) + duration = options['duration'] + jobs = [f] * options['iterations'] + d = Deferred() + def work(res, counter): + try: + f = jobs.pop() + except IndexError: + d.callback(None) + else: + next = f(reactor, duration) + if counter <= 0: + next.addCallback(benchmark_report, duration, f.__module__) + next.addCallbacks(work, d.errback, (counter - 1,)) + work(None, options['warmup']) + return d + +def driver(f, argv): + d = setup_driver(f, argv, reactor) + d.addErrback(log.err) + reactor.callWhenRunning(d.addBoth, lambda ign: reactor.stop()) + reactor.run() + +def multidriver(*f): + jobs = iter(f) + def work(): + for job in jobs: + d = setup_driver(job, sys.argv, reactor) + d.addCallback(lambda ignored: work()) + return + reactor.stop() + reactor.callWhenRunning(work) + reactor.run() Added: pypy/benchmarks/own/twisted/iteration.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/iteration.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,25 @@ + +from __future__ import division + +from benchlib import Client, driver + + +class Client(Client): + def _request(self): + self._reactor.callLater(0.0, self._continue, None) + + + +def main(reactor, duration): + concurrency = 10 + + client = Client(reactor) + d = client.run(concurrency, duration) + return d + + + +if __name__ == '__main__': + import sys + import iteration + driver(iteration.main, sys.argv) Added: pypy/benchmarks/own/twisted/names.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/names.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,47 @@ + +from __future__ import division + +from twisted.names.dns import DNSDatagramProtocol +from twisted.names.server import DNSServerFactory +from twisted.names import hosts, client + +from benchlib import Client, driver + + +class Client(Client): + def __init__(self, reactor, portNumber, timeout): + self._resolver = client.Resolver(servers=[('127.0.0.1', portNumber)]) + self._timeout = timeout + super(Client, self).__init__(reactor) + + + def _request(self): + d = self._resolver.lookupAddress( + 'localhost', timeout=(self._timeout,)) + d.addCallback(self._continue) + d.addErrback(self._stop) + + + + +def main(reactor, duration): + concurrency = 10 + + controller = DNSServerFactory([hosts.Resolver()]) + port = reactor.listenUDP(0, DNSDatagramProtocol(controller)) + # Have queries time out no sooner than the duration of this benchmark so + # we don't have to deal with retries or timeout errors. + client = Client(reactor, port.getHost().port, duration) + d = client.run(concurrency, duration) + def cleanup(passthrough): + d = port.stopListening() + d.addCallback(lambda ign: passthrough) + return d + d.addBoth(cleanup) + return d + + +if __name__ == '__main__': + import sys + import names + driver(names.main, sys.argv) Added: pypy/benchmarks/own/twisted/pb.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/pb.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,61 @@ + +""" +Benchmark for Twisted Spread. +""" + +from __future__ import division + +from twisted.spread.pb import PBServerFactory, PBClientFactory, Root + +from benchlib import Client, driver + + +class BenchRoot(Root): + def remote_discard(self, argument): + pass + + + +class Client(Client): + _structure = [ + 'hello' * 100, + {'foo': 'bar', + 'baz': 100, + u'these are bytes': (1, 2, 3)}] + + def __init__(self, reactor, port): + super(Client, self).__init__(reactor) + self._port = port + + + def run(self, *args, **kwargs): + def connected(reference): + self._reference = reference + return super(Client, self).run(*args, **kwargs) + client = PBClientFactory() + d = client.getRootObject() + d.addCallback(connected) + self._reactor.connectTCP('127.0.0.1', self._port, client) + return d + + + def _request(self): + d = self._reference.callRemote('discard', self._structure) + d.addCallback(self._continue) + d.addErrback(self._stop) + + +def main(reactor, duration): + concurrency = 15 + + server = PBServerFactory(BenchRoot()) + port = reactor.listenTCP(0, server) + client = Client(reactor, port.getHost().port) + d = client.run(concurrency, duration) + return d + + +if __name__ == '__main__': + import sys + import pb + driver(pb.main, sys.argv) Added: pypy/benchmarks/own/twisted/tcp.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/tcp.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,93 @@ + +""" +This benchmarks runs a trivial Twisted TCP echo server and a client pumps as +much data to it as it can in a fixed period of time. + +The size of the string passed to each write call may play a significant +factor in the performance of this benchmark. +""" + +from __future__ import division + +from twisted.internet.defer import Deferred +from twisted.internet.protocol import ServerFactory, ClientCreator, Protocol +from twisted.protocols.wire import Echo + +from benchlib import driver + + +class Counter(Protocol): + count = 0 + + def dataReceived(self, bytes): + self.count += len(bytes) + + + +class Client(object): + _finished = None + + def __init__(self, reactor, port): + self._reactor = reactor + self._port = port + + + def run(self, duration, chunkSize): + self._duration = duration + self._bytes = 'x' * chunkSize + # Set up a connection + cc = ClientCreator(self._reactor, Counter) + d = cc.connectTCP('127.0.0.1', self._port) + d.addCallback(self._connected) + return d + + + def _connected(self, client): + self._client = client + self._stopCall = self._reactor.callLater(self._duration, self._stop) + client.transport.registerProducer(self, False) + self._finished = Deferred() + return self._finished + + + def _stop(self): + self.stopProducing() + self._client.transport.unregisterProducer() + self._finish(self._client.count) + + + def _finish(self, value): + if self._finished is not None: + finished = self._finished + self._finished = None + finished.callback(value) + + + def resumeProducing(self): + self._client.transport.write(self._bytes) + + + def stopProducing(self): + self._client.transport.loseConnection() + + + def connectionLost(self, reason): + self._finish(reason) + + + +def main(reactor, duration): + chunkSize = 16384 + + server = ServerFactory() + server.protocol = Echo + serverPort = reactor.listenTCP(0, server) + client = Client(reactor, serverPort.getHost().port) + d = client.run(duration, chunkSize) + return d + + +if __name__ == '__main__': + import sys + import tcp + driver(tcp.main, sys.argv) Added: pypy/benchmarks/own/twisted/threads.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/threads.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,29 @@ + +from __future__ import division + +from twisted.internet.threads import deferToThread + +from benchlib import Client, driver + + +class Client(Client): + def _request(self): + d = deferToThread(lambda: None) + d.addCallback(self._continue) + d.addErrback(self._stop) + + + +def main(reactor, duration): + concurrency = 10 + + client = Client(reactor) + d = client.run(concurrency, duration) + return d + + + +if __name__ == '__main__': + import sys + import threads + driver(threads.main, sys.argv) Added: pypy/benchmarks/own/twisted/web.py ============================================================================== --- (empty file) +++ pypy/benchmarks/own/twisted/web.py Fri Mar 5 17:20:22 2010 @@ -0,0 +1,76 @@ + +""" +This benchmark runs a trivial Twisted Web server and client and makes as +many requests as it can in a fixed period of time. + +A significant problem with this benchmark is the lack of persistent +connections in the HTTP client. Lots of TCP connections means lots of +overhead in the kernel that's not really what we're trying to benchmark. +Plus lots of sockets end up in TIME_WAIT which has a (briefly) persistent +effect on system-wide performance and makes consecutive runs of the +benchmark vary wildly in their results. +""" + +from __future__ import division + +from twisted.internet.protocol import Protocol +from twisted.internet.defer import Deferred +from twisted.web.server import Site +from twisted.web.static import Data +from twisted.web.resource import Resource +from twisted.web.client import ResponseDone, Agent + +from benchlib import Client, driver + + +class BodyConsumer(Protocol): + def __init__(self, finished): + self.finished = finished + + def connectionLost(self, reason): + if reason.check(ResponseDone): + self.finished.callback(None) + else: + self.finished.errback(reason) + + + +class Client(Client): + def __init__(self, reactor, portNumber, agent): + self._requestLocation = 'http://127.0.0.1:%d/' % (portNumber,) + self._agent = agent + super(Client, self).__init__(reactor) + + + def _request(self): + d = self._agent.request('GET', self._requestLocation) + d.addCallback(self._read) + d.addCallback(self._continue) + d.addErrback(self._stop) + + + def _read(self, response): + finished = Deferred() + response.deliverBody(BodyConsumer(finished)) + return finished + + + +def main(reactor, duration): + concurrency = 10 + + root = Resource() + root.putChild('', Data("Hello, world", "text/plain")) + port = reactor.listenTCP( + 0, Site(root), backlog=128, interface='127.0.0.1') + agent = Agent(reactor) + client = Client(reactor, port.getHost().port, agent) + d = client.run(concurrency, duration) + return d + + + +if __name__ == '__main__': + import sys + import web + driver(web.main, sys.argv) Modified: pypy/benchmarks/unladen_swallow/perf.py ============================================================================== --- pypy/benchmarks/unladen_swallow/perf.py (original) +++ pypy/benchmarks/unladen_swallow/perf.py Fri Mar 5 17:20:22 2010 @@ -754,7 +754,7 @@ def MeasureGeneric(python, options, bm_path, bm_env=None, - extra_args=[], iteration_scaling=1): + extra_args=[], iteration_scaling=1, parser=float): """Abstract measurement function for Unladen's bm_* scripts. Based on the values of options.fast/rigorous, will pass -n {5,50,100} to @@ -792,7 +792,7 @@ result, mem_usage = CallAndCaptureOutput(command, bm_env, track_memory=options.track_memory, inherit_env=options.inherit_env) - times = [float(line) for line in result.splitlines()] + times = [parser(line) for line in result.splitlines()] return times, mem_usage From fijal at codespeak.net Fri Mar 5 17:21:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 17:21:36 +0100 (CET) Subject: [pypy-svn] r71811 - pypy/benchmarks/own/twisted Message-ID: <20100305162136.7B54651057@codespeak.net> Author: fijal Date: Fri Mar 5 17:21:34 2010 New Revision: 71811 Modified: pypy/benchmarks/own/twisted/benchlib.py Log: Make sure we don't run out of TCP connections Modified: pypy/benchmarks/own/twisted/benchlib.py ============================================================================== --- pypy/benchmarks/own/twisted/benchlib.py (original) +++ pypy/benchmarks/own/twisted/benchlib.py Fri Mar 5 17:21:34 2010 @@ -34,6 +34,9 @@ 'in %(duration)s seconds)') def benchmark_report(acceptCount, duration, name): + if acceptCount < 10: + reactor.stop() + raise Exception("Run out of TCP connections!") print PRINT_TEMPL % { 'stats' : acceptCount / duration, 'name' : name, From dan at codespeak.net Fri Mar 5 17:37:51 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Fri, 5 Mar 2010 17:37:51 +0100 (CET) Subject: [pypy-svn] r71814 - pypy/branch/micronumpy/pypy/module/micronumpy/test Message-ID: <20100305163751.539CD51057@codespeak.net> Author: dan Date: Fri Mar 5 17:37:49 2010 New Revision: 71814 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Fixed test_get_set_slices() a bit to be (mostly) comptaible with CPython, all other tests pass on both CPython and PyPy now. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Fri Mar 5 17:37:49 2010 @@ -44,9 +44,9 @@ cls.w_compare = cls.space.appexec([], """(): def compare(a, b): + assert a.dtype == type(b[0]) for x, y in zip(a, b): if x != y: return False - assert type(x) == type(y) return True return compare""") cls.w_length = cls.space.appexec([], """(): return 16""") @@ -196,12 +196,11 @@ cls.w_compare = cls.space.appexec([], """(): def compare(a, b): + assert a.dtype == type(b[0]) for x, y in zip(a, b): if x != y: return False - assert type(x) == type(y) return True return compare""") - def test_multidim(self): from numpy import zeros @@ -254,6 +253,7 @@ assert ar[i, j] == i*3+j def test_get_set_slices(self): + skip("We don't raise exceptions like CPython NumPy.") from numpy import array gen_array = self.gen_array compare = self.compare @@ -263,20 +263,21 @@ assert s1[1]==1 s2 = ar[1:3] assert s2[0][0] == 3 - raises(IndexError, ar.__getitem__, 'what a strange index') + raises(ValueError, ar.__getitem__, 'what a strange index') #FIXME: throw this exception raises(IndexError, ar.__getitem__, (2, 2, 2)) #too many raises(IndexError, ar.__getitem__, 5) raises(IndexError, ar.__getitem__, (0, 6)) - #print ar[2:2].shape + assert 0 in ar[2:2].shape assert compare(ar[-1], ar[2]) assert compare(ar[2:3][0], ar[2]) assert compare(ar[1, 0::2], [3, 5]) assert compare(ar[0::2, 0], [0, 6]) + #setitem ar[2] = 3 assert ar[2, 0] == ar[2, 1] == ar[2, 2] == 3 - raises(ValueError, ar.__setitem__, slice(2, 3), [1]) + raises(ValueError, ar.__setitem__, slice(2, 3), [1]) #FIXME: doesn't throw ar[2] = [0, 1, 2] assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) From dan at codespeak.net Fri Mar 5 17:57:48 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Fri, 5 Mar 2010 17:57:48 +0100 (CET) Subject: [pypy-svn] r71815 - pypy/branch/micronumpy/pypy/module/micronumpy/test Message-ID: <20100305165748.0BD1F51057@codespeak.net> Author: dan Date: Fri Mar 5 17:57:47 2010 New Revision: 71815 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Tests now completely CPython NumPy compatible, but we have to skip a test that we don't comply with. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Fri Mar 5 17:57:47 2010 @@ -257,6 +257,7 @@ from numpy import array gen_array = self.gen_array compare = self.compare + #getitem ar = array(gen_array((3,3))) s1 = ar[0] @@ -277,7 +278,7 @@ #setitem ar[2] = 3 assert ar[2, 0] == ar[2, 1] == ar[2, 2] == 3 - raises(ValueError, ar.__setitem__, slice(2, 3), [1]) #FIXME: doesn't throw + ar[2:3] == [1] #FIXME: this probably throws ar[2] = [0, 1, 2] assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) From arigo at codespeak.net Fri Mar 5 18:13:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 18:13:11 +0100 (CET) Subject: [pypy-svn] r71817 - in pypy/trunk/pypy: objspace/flow objspace/flow/test rlib translator/c/test Message-ID: <20100305171311.8D69351057@codespeak.net> Author: arigo Date: Fri Mar 5 18:13:09 2010 New Revision: 71817 Modified: pypy/trunk/pypy/objspace/flow/objspace.py pypy/trunk/pypy/objspace/flow/test/test_objspace.py pypy/trunk/pypy/rlib/runicode.py pypy/trunk/pypy/translator/c/test/test_typed.py Log: Bah. Fix an issue with runicode. It required a bit more hacking at the flow space. Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Fri Mar 5 18:13:09 2010 @@ -370,6 +370,9 @@ def call_args(self, w_callable, args): try: fn = self.unwrap(w_callable) + if hasattr(fn, "_flowspace_rewrite_directly_as_"): + fn = fn._flowspace_rewrite_directly_as_ + w_callable = self.wrap(fn) sc = self.specialcases[fn] # TypeError if 'fn' not hashable except (UnwrapException, KeyError, TypeError): pass 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 Fri Mar 5 18:13:09 2010 @@ -892,6 +892,22 @@ raise TypeError() py.test.raises(Exception, self.codetest, f) + def test__flowspace_rewrite_directly_as_(self): + def g(x): + pass + def f(x): + pass + f._flowspace_rewrite_directly_as_ = g + def h(x): + f(x) + graph = self.codetest(h) + assert self.all_operations(graph) == {'simple_call': 1} + for block in graph.iterblocks(): + if block.operations: + op = block.operations[0] + assert op.opname == 'simple_call' + assert op.args[0] == Constant(g) + class TestFlowObjSpaceDelay(Base): def setup_class(cls): Modified: pypy/trunk/pypy/rlib/runicode.py ============================================================================== --- pypy/trunk/pypy/rlib/runicode.py (original) +++ pypy/trunk/pypy/rlib/runicode.py Fri Mar 5 18:13:09 2010 @@ -16,26 +16,28 @@ # when sizeof(wchar_t) == 4. # Note that Python3 uses a similar implementation. def UNICHR(c): - if we_are_translated(): + assert not we_are_translated() + if c < sys.maxunicode or c > MAXUNICODE: return unichr(c) else: - if c < sys.maxunicode or c > MAXUNICODE: - return unichr(c) - else: - c -= 0x10000 - return (unichr(0xD800 + (c >> 10)) + - unichr(0xDC00 + (c & 0x03FF))) + c -= 0x10000 + return (unichr(0xD800 + (c >> 10)) + + unichr(0xDC00 + (c & 0x03FF))) + UNICHR._flowspace_rewrite_directly_as_ = unichr + # ^^^ NB.: for translation, it's essential to use this hack instead + # of calling unichr() from UNICHR(), because unichr() detects if there + # is a "try:except ValueError" immediately around it. def ORD(u): - if we_are_translated(): - return ord(u) - else: - if isinstance(u, unicode) and len(u) == 2: - ch1 = ord(u[0]) - ch2 = ord(u[1]) - if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: - return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 - return ord(u) + assert not we_are_translated() + if isinstance(u, unicode) and len(u) == 2: + ch1 = ord(u[0]) + ch2 = ord(u[1]) + if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: + return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 + return ord(u) + ORD._flowspace_rewrite_directly_as_ = ord + else: UNICHR = unichr ORD = ord 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 Fri Mar 5 18:13:09 2010 @@ -212,6 +212,18 @@ assert fn(-12) == -42 assert fn(sys.maxint) == -42 + def test_UNICHR(self): + from pypy.rlib.runicode import UNICHR + def f(x): + try: + return ord(UNICHR(x)) + except ValueError: + return -42 + fn = self.getcompiled(f, [int]) + assert fn(65) == 65 + assert fn(-12) == -42 + assert fn(sys.maxint) == -42 + def test_list_indexerror(self): def f(i): lst = [123, 456] From fijal at codespeak.net Fri Mar 5 18:26:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 18:26:21 +0100 (CET) Subject: [pypy-svn] r71819 - pypy/benchmarks/own/twisted Message-ID: <20100305172621.A87F451059@codespeak.net> Author: fijal Date: Fri Mar 5 18:26:20 2010 New Revision: 71819 Modified: pypy/benchmarks/own/twisted/benchlib.py Log: Better detection of running out of TCP connections Modified: pypy/benchmarks/own/twisted/benchlib.py ============================================================================== --- pypy/benchmarks/own/twisted/benchlib.py (original) +++ pypy/benchmarks/own/twisted/benchlib.py Fri Mar 5 18:26:20 2010 @@ -4,6 +4,8 @@ from twisted.internet import reactor from twisted.python import log +failure = 0 + class Client(object): def __init__(self, reactor): self._reactor = reactor @@ -34,9 +36,10 @@ 'in %(duration)s seconds)') def benchmark_report(acceptCount, duration, name): + global failure if acceptCount < 10: - reactor.stop() - raise Exception("Run out of TCP connections!") + failure = 1 + raise Exception("Run out of TCP connections") print PRINT_TEMPL % { 'stats' : acceptCount / duration, 'name' : name, @@ -77,6 +80,7 @@ d.addErrback(log.err) reactor.callWhenRunning(d.addBoth, lambda ign: reactor.stop()) reactor.run() + sys.exit(failure) def multidriver(*f): jobs = iter(f) From fijal at codespeak.net Fri Mar 5 18:27:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 18:27:58 +0100 (CET) Subject: [pypy-svn] r71820 - pypy/benchmarks Message-ID: <20100305172758.CA4B251059@codespeak.net> Author: fijal Date: Fri Mar 5 18:27:57 2010 New Revision: 71820 Modified: pypy/benchmarks/benchmarks.py Log: Try harder not to run out of tcp connections Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 5 18:27:57 2010 @@ -42,9 +42,15 @@ 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, name, globals(), **opts.get(name, {})) for name in ['web', 'names', 'accepts', 'iteration', 'tcp', 'pb']: + if name == 'accepts': + iteration_scaling = .07 + elif name == 'web': + iteration_scaling = .12 + else: + iteration_scaling = .20 _register_new_bm_twisted(name, 'twisted_' + name, globals(), bm_env={'PYTHONPATH': ':'.join(TWISTED)}, - iteration_scaling=.20) + iteration_scaling=iteration_scaling) _register_new_bm('spitfire', 'spitfire', globals(), extra_args=['--benchmark=spitfire_o4']) _register_new_bm('spitfire', 'spitfire_cstringio', globals(), From arigo at codespeak.net Fri Mar 5 18:31:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 18:31:22 +0100 (CET) Subject: [pypy-svn] r71821 - pypy/trunk/pypy/module/mmap Message-ID: <20100305173122.B1B1D51059@codespeak.net> Author: arigo Date: Fri Mar 5 18:31:21 2010 New Revision: 71821 Modified: pypy/trunk/pypy/module/mmap/interp_mmap.py Log: Capture and expose the RPython-level OSError exception. I cannot really be sure that it's complete, and it's all hard-to-test cases :-( Modified: pypy/trunk/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/trunk/pypy/module/mmap/interp_mmap.py (original) +++ pypy/trunk/pypy/module/mmap/interp_mmap.py Fri Mar 5 18:31:21 2010 @@ -54,7 +54,10 @@ tell.unwrap_spec = ['self'] def descr_size(self): - return self.space.wrap(self.mmap.file_size()) + try: + return self.space.wrap(self.mmap.file_size()) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') descr_size.unwrap_spec = ['self'] def write(self, data): @@ -83,6 +86,8 @@ except RValueError, v: raise OperationError(self.space.w_ValueError, self.space.wrap(v.message)) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') flush.unwrap_spec = ['self', int, int] def move(self, dest, src, count): @@ -96,7 +101,10 @@ def resize(self, newsize): self.check_valid() self.check_resizeable() - self.mmap.resize(newsize) + try: + self.mmap.resize(newsize) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') resize.unwrap_spec = ['self', int] def __len__(self): From arigo at codespeak.net Fri Mar 5 18:56:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 18:56:48 +0100 (CET) Subject: [pypy-svn] r71823 - pypy/trunk/lib-python/modified-2.5.2/ctypes Message-ID: <20100305175648.F173351058@codespeak.net> Author: arigo Date: Fri Mar 5 18:56:47 2010 New Revision: 71823 Modified: pypy/trunk/lib-python/modified-2.5.2/ctypes/__init__.py Log: Comment out the code that detects if we are on an old Mac. Such Macs are too old for building pypy-c's on anyway. Removes one of the only dependencies on the 'gestalt' module. Modified: pypy/trunk/lib-python/modified-2.5.2/ctypes/__init__.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/ctypes/__init__.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/ctypes/__init__.py Fri Mar 5 18:56:47 2010 @@ -23,21 +23,23 @@ from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL -if _os.name == "posix" and _sys.platform == "darwin": - import gestalt +## --- the following is skipped because we don't have 'gestalt' so far, +## --- but we know pypy doesn't compile on Mac OS/X 10.3. +##if _os.name == "posix" and _sys.platform == "darwin": +## import gestalt + +## # gestalt.gestalt("sysv") returns the version number of the +## # currently active system file as BCD. +## # On OS X 10.4.6 -> 0x1046 +## # On OS X 10.2.8 -> 0x1028 +## # See also http://www.rgaros.nl/gestalt/ +## # +## # On OS X 10.3, we use RTLD_GLOBAL as default mode +## # because RTLD_LOCAL does not work at least on some +## # libraries. - # gestalt.gestalt("sysv") returns the version number of the - # currently active system file as BCD. - # On OS X 10.4.6 -> 0x1046 - # On OS X 10.2.8 -> 0x1028 - # See also http://www.rgaros.nl/gestalt/ - # - # On OS X 10.3, we use RTLD_GLOBAL as default mode - # because RTLD_LOCAL does not work at least on some - # libraries. - - if gestalt.gestalt("sysv") < 0x1040: - DEFAULT_MODE = RTLD_GLOBAL +## if gestalt.gestalt("sysv") < 0x1040: +## DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI From arigo at codespeak.net Fri Mar 5 19:26:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 19:26:58 +0100 (CET) Subject: [pypy-svn] r71824 - in pypy/trunk/pypy/rpython/lltypesystem/module: . test Message-ID: <20100305182658.E3B4D51057@codespeak.net> Author: arigo Date: Fri Mar 5 19:26:57 2010 New Revision: 71824 Modified: pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Test and fix. On Mac OS/X, this triggers a use case where the C function ldexp() fails to set errno=ERANGE in case it overflows, but where we still really want the OverflowError from RPython. 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 Fri Mar 5 19:26:57 2010 @@ -7,6 +7,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.rlib.rarithmetic import isinf math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE, sandboxsafe=True) @@ -26,16 +27,24 @@ def ll_math_frexp(x): exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - mantissa = math_frexp(x, exp_p) - exponent = rffi.cast(lltype.Signed, exp_p[0]) - lltype.free(exp_p, flavor='raw') + try: + _error_reset() + mantissa = math_frexp(x, exp_p) + _check_error(mantissa) + exponent = rffi.cast(lltype.Signed, exp_p[0]) + finally: + lltype.free(exp_p, flavor='raw') return (mantissa, exponent) def ll_math_modf(x): intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw') - fracpart = math_modf(x, intpart_p) - intpart = intpart_p[0] - lltype.free(intpart_p, flavor='raw') + try: + _error_reset() + fracpart = math_modf(x, intpart_p) + _check_error(fracpart) + intpart = intpart_p[0] + finally: + lltype.free(intpart_p, flavor='raw') return (fracpart, intpart) def ll_math_ldexp(x, exp): @@ -50,6 +59,8 @@ ERANGE = errno.ERANGE def _check_error(x): errno = rposix.get_errno() + if isinf(x): + errno = ERANGE if errno: if errno == ERANGE: if not x: Modified: pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py Fri Mar 5 19:26:57 2010 @@ -45,3 +45,26 @@ # underflows give 0.0 with no exception raised assert f(1.0, -10000) == 0.0 # sanity-check the host Python assert self.interpret(f, [1.0, -10000]) == 0.0 + + def test_overflow_1(self): + # this (probably, depending on platform) tests the case + # where the C function pow() sets ERANGE. + def f(x, y): + try: + return math.pow(x, y) + except OverflowError: + return -42.0 + + assert self.interpret(f, [10.0, 40000.0]) == -42.0 + + def test_overflow_2(self): + # this (not on Linux but on Mac OS/X at least) tests the case + # where the C function ldexp() does not set ERANGE, but + # returns +infinity. + def f(x, y): + try: + return math.ldexp(x, y) + except OverflowError: + return -42.0 + + assert self.interpret(f, [10.0, 40000]) == -42.0 From arigo at codespeak.net Fri Mar 5 19:33:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Mar 2010 19:33:27 +0100 (CET) Subject: [pypy-svn] r71825 - pypy/build/bot2/pypybuildbot Message-ID: <20100305183327.C06B851057@codespeak.net> Author: arigo Date: Fri Mar 5 19:33:26 2010 New Revision: 71825 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Update. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 5 19:33:26 2010 @@ -67,11 +67,22 @@ lib_python=True, app_tests=True) +jit_translation_args = ['-Ojit', '--gc=hybrid', + '--gcrootfinder=asmgcc', + '--jit-debug=steps'] + pypyJITTranslatedTestFactory = pypybuilds.Translated( - translationArgs=['-Ojit', '--gc=hybrid', - '--gcrootfinder=asmgcc', - '--jit-debug=steps'], - targetArgs = [], #'--withoutmod-thread'], + translationArgs=jit_translation_args, + targetArgs=[], + lib_python=True, + pypyjit=True, + app_tests=True, + ) + +pypyJITTranslatedTestFactoryWin = pypybuilds.Translated( + platform="win32", + translationArgs=jit_translation_args, + targetArgs=[], lib_python=True, pypyjit=True, app_tests=True, @@ -191,7 +202,7 @@ {"name" : JITWIN32, "slavenames": ["bigboard"], 'builddir' : JITWIN32, - 'factory' : pypyJITTranslatedTestFactory, + 'factory' : pypyJITTranslatedTestFactoryWin, 'category' : 'jit', }, {"name": JITONLYLINUX32, From fijal at codespeak.net Fri Mar 5 19:45:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 19:45:53 +0100 (CET) Subject: [pypy-svn] r71826 - pypy/benchmarks Message-ID: <20100305184553.E842B51057@codespeak.net> Author: fijal Date: Fri Mar 5 19:45:52 2010 New Revision: 71826 Modified: pypy/benchmarks/benchmarks.py Log: Kill accepts for now, we run out of TCP connections a bit too easily Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 5 19:45:52 2010 @@ -41,7 +41,7 @@ for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, name, globals(), **opts.get(name, {})) -for name in ['web', 'names', 'accepts', 'iteration', 'tcp', 'pb']: +for name in ['web', 'names', 'iteration', 'tcp', 'pb']: # accepts if name == 'accepts': iteration_scaling = .07 elif name == 'web': From fijal at codespeak.net Fri Mar 5 19:56:57 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 19:56:57 +0100 (CET) Subject: [pypy-svn] r71827 - pypy/benchmarks Message-ID: <20100305185657.E6FD551057@codespeak.net> Author: fijal Date: Fri Mar 5 19:56:56 2010 New Revision: 71827 Modified: pypy/benchmarks/benchmarks.py Log: Reintroduce accepts Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 5 19:56:56 2010 @@ -41,13 +41,8 @@ for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, name, globals(), **opts.get(name, {})) -for name in ['web', 'names', 'iteration', 'tcp', 'pb']: # accepts - if name == 'accepts': - iteration_scaling = .07 - elif name == 'web': - iteration_scaling = .12 - else: - iteration_scaling = .20 +for name in ['web', 'names', 'iteration', 'tcp', 'pb', 'accepts']: + iteration_scaling = .20 _register_new_bm_twisted(name, 'twisted_' + name, globals(), bm_env={'PYTHONPATH': ':'.join(TWISTED)}, iteration_scaling=iteration_scaling) From fijal at codespeak.net Fri Mar 5 23:51:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 23:51:23 +0100 (CET) Subject: [pypy-svn] r71828 - pypy/benchmarks Message-ID: <20100305225123.6EF4351058@codespeak.net> Author: fijal Date: Fri Mar 5 23:51:20 2010 New Revision: 71828 Modified: pypy/benchmarks/benchmarks.py Log: disable accepts and change iteration scaling for web Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 5 23:51:20 2010 @@ -41,8 +41,11 @@ for name in ['float', 'nbody_modified', 'meteor-contest', 'fannkuch', 'spectral-norm', 'chaos', 'telco']: _register_new_bm(name, name, globals(), **opts.get(name, {})) -for name in ['web', 'names', 'iteration', 'tcp', 'pb', 'accepts']: - iteration_scaling = .20 +for name in ['web', 'names', 'iteration', 'tcp', 'pb']:#, 'accepts']: + if name == 'web': + iteration_scaling = .12 + else: + iteration_scaling = .20 _register_new_bm_twisted(name, 'twisted_' + name, globals(), bm_env={'PYTHONPATH': ':'.join(TWISTED)}, iteration_scaling=iteration_scaling) From fijal at codespeak.net Fri Mar 5 23:56:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 5 Mar 2010 23:56:56 +0100 (CET) Subject: [pypy-svn] r71829 - pypy/build/bot2/pypybuildbot Message-ID: <20100305225656.060B651058@codespeak.net> Author: fijal Date: Fri Mar 5 23:56:55 2010 New Revision: 71829 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Pass branch to runner.py Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Mar 5 23:56:55 2010 @@ -133,7 +133,8 @@ command=["python", "runner.py", '--output-filename', 'result.json', '--pypy-c', '../build/pypy/translator/goal/pypy-c', '--upload', '--force-host', 'bigdog', - '--revision', WithProperties('%(got_revision)s')], + '--revision', WithProperties('%(got_revision)s'), + '--branch', WithProperties('%(branch)s')], workdir='./benchmarks', haltOnFailure=True)) # a bit obscure hack to get both os.path.expand and a property @@ -147,6 +148,7 @@ '--pypy-c', '../build/pypy/translator/goal/pypy-c', '--revision', WithProperties('%(got_revision)s'), '--upload', '--force-host', 'bigdog', + '--branch', WithProperties('%(branch)s'), '--args', ',--jit threshold=1000000000'], workdir='./benchmarks', haltOnFailure=True)) From fijal at codespeak.net Sat Mar 6 00:11:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 00:11:12 +0100 (CET) Subject: [pypy-svn] r71831 - in pypy/trunk/pypy/jit: backend/x86 metainterp Message-ID: <20100305231112.5FF5F51058@codespeak.net> Author: fijal Date: Sat Mar 6 00:11:09 2010 New Revision: 71831 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/runner.py pypy/trunk/pypy/jit/metainterp/history.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/resume.py Log: (fijal, arigo reviewing) Merge cleanup-warnings branch. This branch cleans up warnings that show up during translation. There are still gc-related warnings left. Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Sat Mar 6 00:11:09 2010 @@ -100,6 +100,7 @@ mc2 = None mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE _float_constants = None + _regalloc = None def __init__(self, cpu, translate_support_code=False, failargs_limit=1000): Modified: pypy/trunk/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/runner.py Sat Mar 6 00:11:09 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.objectmodel import we_are_translated -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, compile from pypy.jit.backend.x86.assembler import Assembler386 from pypy.jit.backend.x86.regalloc import FORCE_INDEX_OFS from pypy.jit.backend.x86.profagent import ProfileAgent @@ -141,3 +141,19 @@ import pypy.jit.metainterp.executor pypy.jit.metainterp.executor.make_execute_list(CPU) + +# silence warnings + +history.LoopToken._x86_param_depth = 0 +history.LoopToken._x86_arglocs = (None, None) +history.LoopToken._x86_frame_depth = 0 +history.LoopToken._x86_bootstrap_code = 0 +history.LoopToken._x86_direct_bootstrap_code = 0 +history.LoopToken._x86_failure_recovery_bytecode = 0 +history.LoopToken._x86_adr_jump_offset = 0 +history.LoopToken._x86_loop_code = 0 +history.LoopToken._x86_current_depths = (0, 0) + +compile._DoneWithThisFrameDescr._x86_current_depths = (0, 0) +compile._DoneWithThisFrameDescr._x86_failure_recovery_bytecode = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset = 0 Modified: pypy/trunk/pypy/jit/metainterp/history.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/history.py (original) +++ pypy/trunk/pypy/jit/metainterp/history.py Sat Mar 6 00:11:09 2010 @@ -125,6 +125,31 @@ def _clone_if_mutable(self): return self + def get_extra_info(self): + """ Implement in call descr + """ + raise NotImplementedError + + def is_array_of_pointers(self): + """ Implement for array descr + """ + raise NotImplementedError + + def is_array_of_floats(self): + """ Implement for array descr + """ + raise NotImplementedError + + def is_pointer_field(self): + """ Implement for field descr + """ + raise NotImplementedError + + def is_float_field(self): + """ Implement for field descr + """ + raise NotImplementedError + class AbstractFailDescr(AbstractDescr): index = -1 @@ -685,6 +710,7 @@ terminating = False # see TerminatingLoopToken in compile.py # specnodes = ... # and more data specified by the backend when the loop is compiled + number = 0 def __init__(self, number=0): self.number = number @@ -864,6 +890,7 @@ compiled_count = 0 enter_count = 0 aborted_count = 0 + history = None def __init__(self): self.loops = [] Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Sat Mar 6 00:11:09 2010 @@ -47,6 +47,7 @@ last_guard_index = -1 level = LEVEL_UNKNOWN + known_class = None def __init__(self, box): self.box = box @@ -123,6 +124,21 @@ # meaning it has been forced. return self.box is None + def getfield(self, ofs, default): + raise NotImplementedError + + def setfield(self, ofs, value): + raise NotImplementedError + + def getitem(self, index): + raise NotImplementedError + + def getlength(self): + raise NotImplementedError + + def setitem(self, index, value): + raise NotImplementedError + class ConstantValue(OptValue): level = LEVEL_CONSTANT @@ -172,6 +188,8 @@ def _make_virtual(self, modifier): raise NotImplementedError("abstract base") + def _really_force(self): + raise NotImplementedError("abstract base") def get_fielddescrlist_cache(cpu): if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'): Modified: pypy/trunk/pypy/jit/metainterp/resume.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resume.py (original) +++ pypy/trunk/pypy/jit/metainterp/resume.py Sat Mar 6 00:11:09 2010 @@ -397,6 +397,8 @@ def set_content(self, fieldnums): self.fieldnums = fieldnums + def debug_prints(self): + raise NotImplementedError class AbstractVirtualStructInfo(AbstractVirtualInfo): def __init__(self, fielddescrs): From fijal at codespeak.net Sat Mar 6 00:15:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 00:15:02 +0100 (CET) Subject: [pypy-svn] r71832 - pypy/branch/cleanup-warnings Message-ID: <20100305231502.5B02F51058@codespeak.net> Author: fijal Date: Sat Mar 6 00:15:00 2010 New Revision: 71832 Removed: pypy/branch/cleanup-warnings/ Log: Remove merged branch From fijal at codespeak.net Sat Mar 6 00:31:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 00:31:55 +0100 (CET) Subject: [pypy-svn] r71833 - pypy/trunk/pypy/tool Message-ID: <20100305233155.D1D0551058@codespeak.net> Author: fijal Date: Sat Mar 6 00:31:54 2010 New Revision: 71833 Added: pypy/trunk/pypy/tool/progressbar.py (contents, props changed) pypy/trunk/pypy/tool/terminal.py (contents, props changed) Modified: pypy/trunk/pypy/tool/logparser.py Log: Having fun with fancier progress bars. Comes from here: http://nadiana.com/animated-terminal-progress-bar-in-python I like it more than the previous one. Also make sure we don't output png to stdout Modified: pypy/trunk/pypy/tool/logparser.py ============================================================================== --- pypy/trunk/pypy/tool/logparser.py (original) +++ pypy/trunk/pypy/tool/logparser.py Sat Mar 6 00:31:54 2010 @@ -9,6 +9,7 @@ import autopath import sys, re from pypy.rlib.debug import DebugLog +from pypy.tool import progressbar def parse_log_file(filename, verbose=True): r_start = re.compile(r"\[([0-9a-fA-F]+)\] \{([\w-]+)$") @@ -29,14 +30,23 @@ lines = f.readlines() f.close() # + if sys.stdout.isatty(): + progress = progressbar.ProgressBar(color='green') + single_percent = len(lines) / 100 if verbose: - vnext = 0 + vnext = single_percent else: vnext = len(lines) + counter = 0 for i, line in enumerate(lines): if i == vnext: - sys.stderr.write('%d%%..' % int(100.0*i/len(lines))) - vnext += 500000 + counter += 1 + if sys.stdout.isatty(): + progress.render(counter) + vnext += single_percent + else: + sys.stderr.write('%d%%..' % int(100.0*i/len(lines))) + vnext += 500000 line = line.rstrip() match = r_start.match(line) if match: @@ -358,13 +368,13 @@ if __name__ == '__main__': import getopt - if len(sys.argv) < 2: + if len(sys.argv) < 3: print __doc__ sys.exit(2) action = sys.argv[1] func, longopts = ACTIONS[action] options, args = getopt.gnu_getopt(sys.argv[2:], '', longopts) - if len(args) != 1: + if len(args) != 2: print __doc__ sys.exit(2) @@ -373,4 +383,4 @@ assert name.startswith('--') kwds[name[2:]] = value log = parse_log_file(args[0]) - func(log, **kwds) + func(log, args[1], **kwds) Added: pypy/trunk/pypy/tool/progressbar.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/tool/progressbar.py Sat Mar 6 00:31:54 2010 @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Copyright: 2009 Nadia Alramli +# License: BSD +"""Draws an animated terminal progress bar +Usage: + p = ProgressBar("blue") + p.render(percentage, message) +""" + +from pypy.tool import terminal +import sys + +class ProgressBar(object): + """Terminal progress bar class""" + TEMPLATE = ( + '%(percent)-2s%% %(color)s%(progress)s%(normal)s%(empty)s %(message)s\n' + ) + PADDING = 7 + + def __init__(self, color=None, width=None, block='?', empty=' '): + """ + color -- color name (BLUE GREEN CYAN RED MAGENTA YELLOW WHITE BLACK) + width -- bar width (optinal) + block -- progress display character (default '?') + empty -- bar display character (default ' ') + """ + if color: + self.color = getattr(terminal, color.upper()) + else: + self.color = '' + if width and width < terminal.COLUMNS - self.PADDING: + self.width = width + else: + # Adjust to the width of the terminal + self.width = terminal.COLUMNS - self.PADDING + self.block = block + self.empty = empty + self.progress = None + self.lines = 0 + + def render(self, percent, message = ''): + """Print the progress bar + percent -- the progress percentage % + message -- message string (optional) + """ + inline_msg_len = 0 + if message: + # The length of the first line in the message + inline_msg_len = len(message.splitlines()[0]) + if inline_msg_len + self.width + self.PADDING > terminal.COLUMNS: + # The message is too long to fit in one line. + # Adjust the bar width to fit. + bar_width = terminal.COLUMNS - inline_msg_len -self.PADDING + else: + bar_width = self.width + + # Check if render is called for the first time + if self.progress != None: + self.clear() + self.progress = (bar_width * percent) / 100 + data = self.TEMPLATE % { + 'percent': percent, + 'color': self.color, + 'progress': self.block * self.progress, + 'normal': terminal.NORMAL, + 'empty': self.empty * (bar_width - self.progress), + 'message': message + } + sys.stdout.write(data) + sys.stdout.flush() + # The number of lines printed + self.lines = len(data.splitlines()) + + def clear(self): + """Clear all printed lines""" + sys.stdout.write( + self.lines * (terminal.UP + terminal.BOL + terminal.CLEAR_EOL) + ) Added: pypy/trunk/pypy/tool/terminal.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/tool/terminal.py Sat Mar 6 00:31:54 2010 @@ -0,0 +1,81 @@ +# Copyright: 2009 Nadia Alramli +# License: BSD + +"""Terminal controller module +Example of usage: + print BG_BLUE + 'Text on blue background' + NORMAL + print BLUE + UNDERLINE + 'Blue underlined text' + NORMAL + print BLUE + BG_YELLOW + BOLD + 'text' + NORMAL +""" + +import sys + +# The current module +MODULE = sys.modules[__name__] + +COLORS = "BLUE GREEN CYAN RED MAGENTA YELLOW WHITE BLACK".split() +# List of terminal controls, you can add more to the list. +CONTROLS = { + 'BOL':'cr', 'UP':'cuu1', 'DOWN':'cud1', 'LEFT':'cub1', 'RIGHT':'cuf1', + 'CLEAR_SCREEN':'clear', 'CLEAR_EOL':'el', 'CLEAR_BOL':'el1', + 'CLEAR_EOS':'ed', 'BOLD':'bold', 'BLINK':'blink', 'DIM':'dim', + 'REVERSE':'rev', 'UNDERLINE':'smul', 'NORMAL':'sgr0', + 'HIDE_CURSOR':'cinvis', 'SHOW_CURSOR':'cnorm' +} + +# List of numeric capabilities +VALUES = { + 'COLUMNS':'cols', # Width of the terminal (None for unknown) + 'LINES':'lines', # Height of the terminal (None for unknown) + 'MAX_COLORS': 'colors', +} + +def default(): + """Set the default attribute values""" + for color in COLORS: + setattr(MODULE, color, '') + setattr(MODULE, 'BG_%s' % color, '') + for control in CONTROLS: + setattr(MODULE, control, '') + for value in VALUES: + setattr(MODULE, value, None) + +def setup(): + """Set the terminal control strings""" + # Initializing the terminal + curses.setupterm() + # Get the color escape sequence template or '' if not supported + # setab and setaf are for ANSI escape sequences + bgColorSeq = curses.tigetstr('setab') or curses.tigetstr('setb') or '' + fgColorSeq = curses.tigetstr('setaf') or curses.tigetstr('setf') or '' + + for color in COLORS: + # Get the color index from curses + colorIndex = getattr(curses, 'COLOR_%s' % color) + # Set the color escape sequence after filling the template with index + setattr(MODULE, color, curses.tparm(fgColorSeq, colorIndex)) + # Set background escape sequence + setattr( + MODULE, 'BG_%s' % color, curses.tparm(bgColorSeq, colorIndex) + ) + for control in CONTROLS: + # Set the control escape sequence + setattr(MODULE, control, curses.tigetstr(CONTROLS[control]) or '') + for value in VALUES: + # Set terminal related values + setattr(MODULE, value, curses.tigetnum(VALUES[value])) + +def render(text): + """Helper function to apply controls easily + Example: + apply("%(GREEN)s%(BOLD)stext%(NORMAL)s") -> a bold green text + """ + return text % MODULE.__dict__ + +try: + import curses + setup() +except Exception, e: + # There is a failure; set all attributes to default + print 'Warning: %s' % e + default() From fijal at codespeak.net Sat Mar 6 01:53:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 01:53:35 +0100 (CET) Subject: [pypy-svn] r71834 - pypy/benchmarks Message-ID: <20100306005335.0397151058@codespeak.net> Author: fijal Date: Sat Mar 6 01:53:34 2010 New Revision: 71834 Modified: pypy/benchmarks/benchmarks.py Log: resort back to original measurments scheme (100/number) request count Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Sat Mar 6 01:53:34 2010 @@ -21,7 +21,7 @@ def Measure(python, options): def parser(line): number = float(line.split(" ")[0]) - return 3000/number + return 100/number bm_path = relative('own', 'twisted', name + '.py') return MeasureGeneric(python, options, bm_path, parser=parser, **opts) Measure.func_name = 'Measure' + name.capitalize() From fijal at codespeak.net Sat Mar 6 01:56:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 01:56:35 +0100 (CET) Subject: [pypy-svn] r71835 - pypy/benchmarks Message-ID: <20100306005635.7260451058@codespeak.net> Author: fijal Date: Sat Mar 6 01:56:33 2010 New Revision: 71835 Modified: pypy/benchmarks/benchmarks.py Log: Scale tcp, a bit by hand now Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Sat Mar 6 01:56:33 2010 @@ -21,7 +21,10 @@ def Measure(python, options): def parser(line): number = float(line.split(" ")[0]) - return 100/number + if name == 'tcp': + return 100*1024*1024/number + else: + return 100/number bm_path = relative('own', 'twisted', name + '.py') return MeasureGeneric(python, options, bm_path, parser=parser, **opts) Measure.func_name = 'Measure' + name.capitalize() From fijal at codespeak.net Sat Mar 6 03:31:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 03:31:16 +0100 (CET) Subject: [pypy-svn] r71837 - pypy/branch/ctypes-configure-cache Message-ID: <20100306023116.7F65251058@codespeak.net> Author: fijal Date: Sat Mar 6 03:31:09 2010 New Revision: 71837 Added: pypy/branch/ctypes-configure-cache/ - copied from r71835, pypy/trunk/ Log: A branch to introduce caching to ctypes_configure From fijal at codespeak.net Sat Mar 6 03:33:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 03:33:07 +0100 (CET) Subject: [pypy-svn] r71838 - in pypy/branch/ctypes-configure-cache/ctypes_configure: . test Message-ID: <20100306023307.6A57251058@codespeak.net> Author: fijal Date: Sat Mar 6 03:33:01 2010 New Revision: 71838 Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/cbuild.py pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py Log: Introduce dumping of cache to ctypes configure. Cannot handle nested structs now (test pending), also nobody uses it so far Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/cbuild.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/cbuild.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/cbuild.py Sat Mar 6 03:33:01 2010 @@ -5,7 +5,7 @@ debug = 0 -configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') +configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure-') class ExternalCompilationInfo(object): Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py Sat Mar 6 03:33:01 2010 @@ -151,11 +151,13 @@ return try_compile([self.path], eci) -def configure(CConfig, noerr=False): +def configure(CConfig, savecache=None, noerr=False): """Examine the local system by running the C compiler. The CConfig class contains CConfigEntry attribues that describe what should be inspected; configure() returns a dict mapping names to the results. + + savecache contains a path where to save (append) results of a call """ for attr in ['_includes_', '_libraries_', '_sources_', '_library_dirs_', '_include_dirs_', '_header_']: @@ -164,7 +166,7 @@ for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigEntry): - entries.append((key, value)) + entries.append((key, value)) if entries: # can be empty if there are only CConfigSingleEntries writer = _CWriter(CConfig) @@ -202,15 +204,36 @@ writer.write_header() res[key] = value.question(writer.ask_gcc) + if savecache is not None: + f = py.path.local(savecache).open("w") + f.write('import ctypes\n\n') + for key, val in res.items(): + entry = getattr(CConfig, key) + if isinstance(val, int): + f.write("%s = %d\n" % (key, val)) + elif isinstance(val, ctypes._SimpleCData.__class__): + # a simple type + f.write("%s = %s\n" % (key, ctypes_repr(val))) + elif isinstance(val, ctypes.Structure.__class__): + f.write("class %s(ctypes.Structure):\n" % key) + f.write(" _fields_ = [\n") + for k, v in val._fields_: + f.write(" ('%s', %s),\n" % (k, ctypes_repr(v))) + f.write(" ]\n") + else: + raise NotImplementedError("Saving of %r" % (val,)) + f.close() return res +def ctypes_repr(cls): + return "ctypes." + cls.__name__ + # ____________________________________________________________ class CConfigEntry(object): "Abstract base class." - class Struct(CConfigEntry): """An entry in a CConfig class that stands for an externally defined structure. @@ -313,7 +336,6 @@ S.__name__ = name return S - class SimpleType(CConfigEntry): """An entry in a CConfig class that stands for an externally defined simple numeric type. @@ -350,7 +372,6 @@ ctype = fixup_ctype(ctype, self.name, (size, sign)) return ctype - class ConstantInteger(CConfigEntry): """An entry in a CConfig class that stands for an externally defined integer constant. Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py Sat Mar 6 03:33:01 2010 @@ -126,6 +126,32 @@ 'ushort': ctypes.c_ushort, 'XYZZY': 42} +def test_cache(): + configdir = configure.configdir + test_h = configdir.join('test_ctypes_platform2.h') + test_h.write('#define XYZZY 42\n') + + class CConfig: + _compilation_info_ = ExternalCompilationInfo( + pre_include_lines = ["/* a C comment */", + "#include ", + "#include "], + include_dirs = [str(configdir)] + ) + + FILE = configure.Struct('FILE', []) + ushort = configure.SimpleType('unsigned short') + XYZZY = configure.ConstantInteger('XYZZY') + + cachefile = configdir.join('cache') + res = configure.configure(CConfig, savecache=configdir.join('cache')) + d = {} + execfile(str(cachefile), d) + assert d['XYZZY'] == res['XYZZY'] + assert d['ushort'] == res['ushort'] + assert d['FILE']._fields_ == res['FILE']._fields_ + assert d['FILE'].__mro__[1:] == res['FILE'].__mro__[1:] + def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo( From fijal at codespeak.net Sat Mar 6 03:38:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 03:38:30 +0100 (CET) Subject: [pypy-svn] r71839 - pypy/branch/ctypes-configure-cache/ctypes_configure Message-ID: <20100306023830.C728A51058@codespeak.net> Author: fijal Date: Sat Mar 6 03:38:29 2010 New Revision: 71839 Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py Log: a comment and an assert Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py Sat Mar 6 03:38:29 2010 @@ -226,6 +226,9 @@ return res def ctypes_repr(cls): + # ctypes_configure does not support nested structs so far + # so let's ignore it + assert isinstance(cls, ctypes._SimpleCData.__class__) return "ctypes." + cls.__name__ # ____________________________________________________________ From fijal at codespeak.net Sat Mar 6 04:24:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 04:24:48 +0100 (CET) Subject: [pypy-svn] r71840 - pypy/branch/ctypes-configure-cache/pypy/lib/_ctypes/_cache Message-ID: <20100306032448.068BE51058@codespeak.net> Author: fijal Date: Sat Mar 6 04:24:45 2010 New Revision: 71840 Added: pypy/branch/ctypes-configure-cache/pypy/lib/_ctypes/_cache/ (props changed) Log: Add a directory for storing ctypes_configure caches, with ignore on * From fijal at codespeak.net Sat Mar 6 04:37:35 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 04:37:35 +0100 (CET) Subject: [pypy-svn] r71841 - pypy/branch/ctypes-configure-cache/pypy/lib Message-ID: <20100306033735.91DA851058@codespeak.net> Author: fijal Date: Sat Mar 6 04:37:32 2010 New Revision: 71841 Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py Log: port _locale Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py Sat Mar 6 04:37:32 2010 @@ -7,8 +7,8 @@ c_ubyte, c_int, c_char_p, c_wchar_p) from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno -from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + +import os.path size_t = c_int @@ -31,21 +31,33 @@ 'LC_IDENTIFICATION', ) -class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) -for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) +cache_dir = os.path.join(os.path.dirname(__file__), '_ctypes', '_cache') +cache_file = os.path.join(cache_dir, '_locale') try: - locale_config = configure(LocaleConfigure, noerr=True) -except Exception, e: - # should probably be moved into configure() - # as an optional feature - raise ImportError("%s: %s" % (e.__class__, e)) + locale_config = {} + execfile(cache_file, locale_config) +except: + from ctypes_configure.configure import (configure, ExternalCompilationInfo, + ConstantInteger, DefinedConstantInteger, SimpleType) + + class LocaleConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) + for key in _CONSTANTS: + setattr(LocaleConfigure, key, ConstantInteger(key)) + + try: + locale_config = configure(LocaleConfigure, savecache=cache_file, + noerr=True) + except Exception, e: + # should probably be moved into configure() + # as an optional feature + raise ImportError("%s: %s" % (e.__class__, e)) + + del LocaleConfigure for key in _CONSTANTS: globals()[key] = locale_config[key] -del LocaleConfigure del locale_config HAS_LANGINFO = True @@ -297,18 +309,28 @@ for i in range(1, 13): langinfo_names.append("MON_%d" % i) langinfo_names.append("ABMON_%d" % i) - - class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) - nl_item = SimpleType('nl_item') - for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) - config = configure(LanginfoConfigure) + try: + langinfo_cache = os.path.join(cache_dir, '_locale_langinfo') + config = {} + execfile(langinfo_cache, config) + except: + from ctypes_configure.configure import (configure, + ExternalCompilationInfo, + ConstantInteger, DefinedConstantInteger, SimpleType) + + class LanginfoConfigure: + _compilation_info_ = ExternalCompilationInfo( + includes=['langinfo.h']) + nl_item = SimpleType('nl_item') + for key in langinfo_names: + setattr(LanginfoConfigure, key, ConstantInteger(key)) + + config = configure(LanginfoConfigure, savecache=langinfo_cache) + del LanginfoConfigure nl_item = config['nl_item'] for key in langinfo_names: globals()[key] = config[key] - del LanginfoConfigure del config _nl_langinfo = libc.nl_langinfo From dan at codespeak.net Sat Mar 6 05:03:35 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 6 Mar 2010 05:03:35 +0100 (CET) Subject: [pypy-svn] r71842 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100306040335.6D20451058@codespeak.net> Author: dan Date: Sat Mar 6 05:03:32 2010 New Revision: 71842 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Added test for str, skipping for now, passes on CPython NumPy though. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Sat Mar 6 05:03:32 2010 @@ -19,7 +19,6 @@ def coerce_float32(space, w_x): return unwrap_float32(space, space.float(w_x)) - def create_factory(result_factory): def factory(t): return result_factory[t] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Sat Mar 6 05:03:32 2010 @@ -254,13 +254,13 @@ def descr_getitem(self, w_index): space = self.space - validate_index(self, space, w_index) try: space.iter(w_index) except OperationError, e: if not e.match(space, space.w_TypeError): raise w_index = space.newlist([w_index]) + validate_index(self, space, w_index) try: indexes = self._unpack_indexes(space, w_index) except OperationError, e: Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Sat Mar 6 05:03:32 2010 @@ -175,6 +175,22 @@ assert len(x) == 5 raises(ValueError, minimum, ar, zeros(3, dtype=int)) + def test_str(self): + skip("Perfect string formatting is going to be tough.") + from numpy import zeros, array + + z = zeros(shape=(3,)) + assert str(z) == '[ 0. 0. 0.]' + + ar = array([1.0, 2.0, 3.0]) + assert str(ar) == '[ 1. 2. 3.]' + + ar = array([1.5, 2.5, 3.5]) + assert str(ar) == '[ 1.5 2.5 3.5]' + + ar = array([1, 2, 3], dtype=int) + assert str(ar) == '[1 2 3]' + class AppTestMultiDim(object): def setup_class(cls): cls.space = gettestobjspace(usemodules=('micronumpy',)) From fijal at codespeak.net Sat Mar 6 05:10:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 05:10:10 +0100 (CET) Subject: [pypy-svn] r71843 - pypy/branch/ctypes-configure-cache/pypy/lib Message-ID: <20100306041010.B4A7451058@codespeak.net> Author: fijal Date: Sat Mar 6 05:10:08 2010 New Revision: 71843 Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py pypy/branch/ctypes-configure-cache/pypy/lib/ctypes_support.py pypy/branch/ctypes-configure-cache/pypy/lib/resource.py Log: Use caching also in resource Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/_locale.py Sat Mar 6 05:10:08 2010 @@ -6,7 +6,7 @@ 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 -from ctypes_support import get_errno +from ctypes_support import get_errno, cache_dir import os.path @@ -31,13 +31,12 @@ 'LC_IDENTIFICATION', ) -cache_dir = os.path.join(os.path.dirname(__file__), '_ctypes', '_cache') cache_file = os.path.join(cache_dir, '_locale') try: locale_config = {} execfile(cache_file, locale_config) -except: +except (IOError, OSError): from ctypes_configure.configure import (configure, ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, SimpleType) Modified: pypy/branch/ctypes-configure-cache/pypy/lib/ctypes_support.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/ctypes_support.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/ctypes_support.py Sat Mar 6 05:10:08 2010 @@ -6,6 +6,9 @@ import ctypes import ctypes.util import sys +import os.path + +cache_dir = os.path.join(os.path.dirname(__file__), '_ctypes', '_cache') # __________ the standard C library __________ Modified: pypy/branch/ctypes-configure-cache/pypy/lib/resource.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/resource.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/resource.py Sat Mar 6 05:10:08 2010 @@ -2,13 +2,11 @@ if sys.platform == 'win32': raise ImportError('resource module not available for win32') +import os.path from ctypes_support import standard_c_lib as libc -from ctypes_support import get_errno +from ctypes_support import get_errno, cache_dir from ctypes import Structure, c_int, c_long, byref, sizeof from errno import EINVAL, EPERM -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, - SimpleType) import _structseq class error(Exception): @@ -53,16 +51,28 @@ _getpagesize = None # Setup our configure -class ResourceConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) - rlim_t = SimpleType('rlim_t') -for key in _CONSTANTS: - setattr(ResourceConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(ResourceConfigure, key, DefinedConstantInteger(key)) + +cache_file = os.path.join(cache_dir, 'resource') +try: + config = {} + execfile(cache_file, config) +except (IOError, OSError): + from ctypes_configure.configure import (configure, + ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, + SimpleType) + + class ResourceConfigure: + _compilation_info_ = ExternalCompilationInfo( + includes=['sys/resource.h']) + rlim_t = SimpleType('rlim_t') + for key in _CONSTANTS: + setattr(ResourceConfigure, key, ConstantInteger(key)) + for key in _OPTIONAL_CONSTANTS: + setattr(ResourceConfigure, key, DefinedConstantInteger(key)) + + config = configure(ResourceConfigure, savecache=cache_file) # Configure constants and types -config = configure(ResourceConfigure) rlim_t = config['rlim_t'] sizeof_rlim_t = 1<<(sizeof(rlim_t) * 8) for key in _CONSTANTS: From dan at codespeak.net Sat Mar 6 05:14:16 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 6 Mar 2010 05:14:16 +0100 (CET) Subject: [pypy-svn] r71844 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100306041416.EC64C51058@codespeak.net> Author: dan Date: Sat Mar 6 05:14:15 2010 New Revision: 71844 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Log: Marginally improved sdarray str() and repr(). Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Mar 6 05:14:15 2010 @@ -232,21 +232,25 @@ descr_len.unwrap_spec = ['self'] def str(self): - return ', '.join([str(x) for x in self.storage]) + strings = [str(x) for x in self.storage] + maxlen = max([len(x) for x in strings]) + return strings, maxlen def descr_str(self): space = self.space #beautiful, as in numpy - strs=[str(x) for x in self.storage] - maxlen=max([len(x) for x in strs]) + strings, maxlen = self.str() return space.wrap( - "[%s]" % ' '.join(["%-*s"%(maxlen, s) for s in strs]) + "[%s]" % ' '.join(["%-*s"%(maxlen, s) for s in strings]) ) descr_str.unwrap_spec = ['self'] def descr_repr(self): space = self.space - return space.wrap("array([%s])" % self.str()) + strings, maxlen = self.str() + return space.wrap( + "array([%s])" % ', '.join(["%-*s"%(maxlen, s) for s in strings]) + ) descr_repr.unwrap_spec = ['self'] NumArray.typedef = TypeDef('ndarray', base_typedef, From fijal at codespeak.net Sat Mar 6 05:14:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 05:14:21 +0100 (CET) Subject: [pypy-svn] r71845 - in pypy/branch/ctypes-configure-cache/ctypes_configure: . test Message-ID: <20100306041421.DA6AE5105D@codespeak.net> Author: fijal Date: Sat Mar 6 05:14:19 2010 New Revision: 71845 Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py Log: A test and a fix Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/configure.py Sat Mar 6 05:14:19 2010 @@ -209,8 +209,10 @@ f.write('import ctypes\n\n') for key, val in res.items(): entry = getattr(CConfig, key) - if isinstance(val, int): + if isinstance(val, (int, long)): f.write("%s = %d\n" % (key, val)) + elif val is None: + f.write("%s = None\n" % key) elif isinstance(val, ctypes._SimpleCData.__class__): # a simple type f.write("%s = %s\n" % (key, ctypes_repr(val))) Modified: pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py (original) +++ pypy/branch/ctypes-configure-cache/ctypes_configure/test/test_configure.py Sat Mar 6 05:14:19 2010 @@ -129,7 +129,8 @@ def test_cache(): configdir = configure.configdir test_h = configdir.join('test_ctypes_platform2.h') - test_h.write('#define XYZZY 42\n') + test_h.write('#define XYZZY 42\n' + "#define large 2147483648L\n") class CConfig: _compilation_info_ = ExternalCompilationInfo( @@ -142,6 +143,9 @@ FILE = configure.Struct('FILE', []) ushort = configure.SimpleType('unsigned short') XYZZY = configure.ConstantInteger('XYZZY') + XUZ = configure.Has('XUZ') + large = configure.DefinedConstantInteger('large') + undef = configure.Defined('really_undefined') cachefile = configdir.join('cache') res = configure.configure(CConfig, savecache=configdir.join('cache')) @@ -151,6 +155,9 @@ assert d['ushort'] == res['ushort'] assert d['FILE']._fields_ == res['FILE']._fields_ assert d['FILE'].__mro__[1:] == res['FILE'].__mro__[1:] + assert d['undef'] == res['undef'] + assert d['large'] == res['large'] + assert d['XUZ'] == res['XUZ'] def test_ifdef(): class CConfig: From fijal at codespeak.net Sat Mar 6 05:26:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 05:26:46 +0100 (CET) Subject: [pypy-svn] r71846 - pypy/branch/ctypes-configure-cache/pypy/lib Message-ID: <20100306042646.964CF51058@codespeak.net> Author: fijal Date: Sat Mar 6 05:26:43 2010 New Revision: 71846 Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_hashlib.py Log: use caching in hashlib Modified: pypy/branch/ctypes-configure-cache/pypy/lib/_hashlib.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/_hashlib.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/_hashlib.py Sat Mar 6 05:26:43 2010 @@ -1,6 +1,8 @@ +import sys from ctypes import * import ctypes.util -from ctypes_configure import configure +from ctypes_support import cache_dir +import os.path # Note: OpenSSL on OS X only provides md5 and sha1 libpath = ctypes.util.find_library('ssl') @@ -16,15 +18,25 @@ else: return buffer(x)[:] -class CConfig: - _compilation_info_ = configure.ExternalCompilationInfo( - includes=['openssl/evp.h'], - ) - EVP_MD = configure.Struct('EVP_MD', - []) - EVP_MD_CTX = configure.Struct('EVP_MD_CTX', - [('digest', c_void_p)]) -c = configure.configure(CConfig) +cache_file = os.path.join(cache_dir, '_hashlib') + +try: + c = {} + execfile(cache_file, c) +except (OSError, IOError): + from ctypes_configure import configure + + class CConfig: + _compilation_info_ = configure.ExternalCompilationInfo( + includes=['openssl/evp.h'], + ) + EVP_MD = configure.Struct('EVP_MD', + []) + EVP_MD_CTX = configure.Struct('EVP_MD_CTX', + [('digest', c_void_p)]) + c = configure.configure(CConfig, savecache=cache_file) + del CConfig + EVP_MD_CTX = c['EVP_MD_CTX'] EVP_MD = c['EVP_MD'] From fijal at codespeak.net Sat Mar 6 05:31:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 05:31:09 +0100 (CET) Subject: [pypy-svn] r71847 - pypy/branch/ctypes-configure-cache/pypy/lib Message-ID: <20100306043109.2098F51058@codespeak.net> Author: fijal Date: Sat Mar 6 05:31:06 2010 New Revision: 71847 Modified: pypy/branch/ctypes-configure-cache/pypy/lib/syslog.py Log: use caching for syslog Modified: pypy/branch/ctypes-configure-cache/pypy/lib/syslog.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/syslog.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/syslog.py Sat Mar 6 05:31:06 2010 @@ -6,13 +6,12 @@ """ import sys +import os.path if sys.platform == 'win32': raise ImportError("No syslog on Windows") -from ctypes_support import standard_c_lib as libc +from ctypes_support import standard_c_lib as libc, cache_dir from ctypes import c_int, c_char_p -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) _CONSTANTS = ( 'LOG_EMERG', @@ -61,14 +60,23 @@ ('LOG_UUCP', 'LOG_MAIL'), ) -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) +cache_file = os.path.join(cache_dir, 'syslog') +try: + config = {} + execfile(cache_file, config) +except (IOError, OSError): + from ctypes_configure.configure import (configure, + ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) + + class SyslogConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) + for key in _CONSTANTS: + setattr(SyslogConfigure, key, ConstantInteger(key)) + for key in _OPTIONAL_CONSTANTS: + setattr(SyslogConfigure, key, DefinedConstantInteger(key)) + + config = configure(SyslogConfigure, savecache=cache_file) -config = configure(SyslogConfigure) for key in _CONSTANTS: globals()[key] = config[key] optional_constants = [] From fijal at codespeak.net Sat Mar 6 05:34:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 05:34:16 +0100 (CET) Subject: [pypy-svn] r71848 - pypy/branch/ctypes-configure-cache/pypy/lib Message-ID: <20100306043416.C026C51058@codespeak.net> Author: fijal Date: Sat Mar 6 05:34:14 2010 New Revision: 71848 Modified: pypy/branch/ctypes-configure-cache/pypy/lib/pyexpat.py Log: Also use caching in pyexpat, although it's compiled as module these days Modified: pypy/branch/ctypes-configure-cache/pypy/lib/pyexpat.py ============================================================================== --- pypy/branch/ctypes-configure-cache/pypy/lib/pyexpat.py (original) +++ pypy/branch/ctypes-configure-cache/pypy/lib/pyexpat.py Sat Mar 6 05:34:14 2010 @@ -1,44 +1,53 @@ import ctypes import ctypes.util -from ctypes_configure import configure from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p +from ctypes_support import cache_dir import sys +import os.path lib = ctypes.CDLL(ctypes.util.find_library('expat')) -class CConfigure: - _compilation_info_ = configure.ExternalCompilationInfo( - includes = ['expat.h'], - libraries = ['expat'], - pre_include_lines = [ - '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], - ) - - XML_Char = configure.SimpleType('XML_Char', ctypes.c_char) - XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') - for name in ['XML_PARAM_ENTITY_PARSING_NEVER', - 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', - 'XML_PARAM_ENTITY_PARSING_ALWAYS']: - locals()[name] = configure.ConstantInteger(name) - - XML_Encoding = configure.Struct('XML_Encoding',[ - ('data', c_void_p), - ('convert', c_void_p), - ('release', c_void_p), - ('map', c_int * 256)]) - XML_Content = configure.Struct('XML_Content',[ - ('numchildren', c_int), - ('children', c_void_p), - ('name', c_char_p), - ('type', c_int), - ('quant', c_int), - ]) - # this is insanely stupid - XML_FALSE = configure.ConstantInteger('XML_FALSE') - XML_TRUE = configure.ConstantInteger('XML_TRUE') +cache_file = os.path.join(cache_dir, 'pyexpat') +try: + info = {} + execfile(cache_file, info) +except (IOError, OSError): + from ctypes_configure import configure + class CConfigure: + _compilation_info_ = configure.ExternalCompilationInfo( + includes = ['expat.h'], + libraries = ['expat'], + pre_include_lines = [ + '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], + ) + + XML_Char = configure.SimpleType('XML_Char', ctypes.c_char) + XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') + for name in ['XML_PARAM_ENTITY_PARSING_NEVER', + 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', + 'XML_PARAM_ENTITY_PARSING_ALWAYS']: + locals()[name] = configure.ConstantInteger(name) + + XML_Encoding = configure.Struct('XML_Encoding',[ + ('data', c_void_p), + ('convert', c_void_p), + ('release', c_void_p), + ('map', c_int * 256)]) + XML_Content = configure.Struct('XML_Content',[ + ('numchildren', c_int), + ('children', c_void_p), + ('name', c_char_p), + ('type', c_int), + ('quant', c_int), + ]) + # this is insanely stupid + XML_FALSE = configure.ConstantInteger('XML_FALSE') + XML_TRUE = configure.ConstantInteger('XML_TRUE') + + info = configure.configure(CConfigure, savecache=cache_file) + -info = configure.configure(CConfigure) for k, v in info.items(): globals()[k] = v From arigo at codespeak.net Sat Mar 6 11:26:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 11:26:19 +0100 (CET) Subject: [pypy-svn] r71849 - pypy/branch/ctypes-configure-cache-2 Message-ID: <20100306102619.0EA2551058@codespeak.net> Author: arigo Date: Sat Mar 6 11:26:17 2010 New Revision: 71849 Added: pypy/branch/ctypes-configure-cache-2/ - copied from r71848, pypy/trunk/ Log: Another branch (sorry) in order to try to implement it in a different way. From arigo at codespeak.net Sat Mar 6 12:16:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 12:16:00 +0100 (CET) Subject: [pypy-svn] r71850 - in pypy/branch/ctypes-configure-cache-2: ctypes_configure pypy/lib pypy/lib/ctypes_config_cache Message-ID: <20100306111600.170875105A@codespeak.net> Author: arigo Date: Sat Mar 6 12:15:59 2010 New Revision: 71850 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/ (props changed) pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/__init__.py (contents, props changed) pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/autopath.py - copied unchanged from r71849, pypy/branch/ctypes-configure-cache-2/pypy/bin/autopath.py pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py (contents, props changed) Removed: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_configure Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py Log: Write just enough to have the syslog version. Note that 'pypy/lib/ctypes_configure' is killed now. Also note that the cache is not generated automatically; you have to call 'syslog.ctc.py' explicitly. The idea is to call all .ctc.py files at the start of a translation. Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py Sat Mar 6 12:15:59 2010 @@ -588,6 +588,19 @@ # ____________________________________________________________ +def dumpcache(referencefilename, filename, config): + dirname = os.path.dirname(referencefilename) + filename = os.path.join(dirname, filename) + f = open(filename, 'w') + names = config.keys() + names.sort() + for name in names: + print >> f, '%s = %r' % (name, config[name]) + f.close() + print 'Wrote %s.' % (filename,) + +# ____________________________________________________________ + def get_python_include_dir(): from distutils import sysconfig gcv = sysconfig.get_config_vars() Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/__init__.py ============================================================================== Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py Sat Mar 6 12:15:59 2010 @@ -0,0 +1,79 @@ +""" +'ctypes_configure' source for syslog.py. +Run this to rebuild _syslog_cache.py. +""" + +import autopath +from ctypes_configure.configure import (configure, dumpcache, + ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) + + +_CONSTANTS = ( + 'LOG_EMERG', + 'LOG_ALERT', + 'LOG_CRIT', + 'LOG_ERR', + 'LOG_WARNING', + 'LOG_NOTICE', + 'LOG_INFO', + 'LOG_DEBUG', + + 'LOG_PID', + 'LOG_CONS', + 'LOG_NDELAY', + + 'LOG_KERN', + 'LOG_USER', + 'LOG_MAIL', + 'LOG_DAEMON', + 'LOG_AUTH', + 'LOG_LPR', + 'LOG_LOCAL0', + 'LOG_LOCAL1', + 'LOG_LOCAL2', + 'LOG_LOCAL3', + 'LOG_LOCAL4', + 'LOG_LOCAL5', + 'LOG_LOCAL6', + 'LOG_LOCAL7', +) +_OPTIONAL_CONSTANTS = ( + 'LOG_NOWAIT', + 'LOG_PERROR', + + 'LOG_SYSLOG', + 'LOG_CRON', + 'LOG_UUCP', + 'LOG_NEWS', +) + +# Constant aliases if there are not defined +_ALIAS = ( + ('LOG_SYSLOG', 'LOG_DAEMON'), + ('LOG_CRON', 'LOG_DAEMON'), + ('LOG_NEWS', 'LOG_MAIL'), + ('LOG_UUCP', 'LOG_MAIL'), +) + +class SyslogConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) +for key in _CONSTANTS: + setattr(SyslogConfigure, key, ConstantInteger(key)) +for key in _OPTIONAL_CONSTANTS: + setattr(SyslogConfigure, key, DefinedConstantInteger(key)) + +config = configure(SyslogConfigure) +optional_constants = [] +for key in _OPTIONAL_CONSTANTS: + if config[key] is not None: + optional_constants.append(key) + else: + del config[key] +for alias, key in _ALIAS: + if alias in optional_constants: + continue + config[alias] = config[key] + optional_constants.append(alias) + +config['optional_constants'] = optional_constants +dumpcache(__file__, '_syslog_cache.py', config) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py Sat Mar 6 12:15:59 2010 @@ -9,79 +9,11 @@ if sys.platform == 'win32': raise ImportError("No syslog on Windows") +# load the platform-specific cache made by running syslog.ctc.py +from ctypes_config_cache._syslog_cache import * + from ctypes_support import standard_c_lib as libc from ctypes import c_int, c_char_p -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) - -_CONSTANTS = ( - 'LOG_EMERG', - 'LOG_ALERT', - 'LOG_CRIT', - 'LOG_ERR', - 'LOG_WARNING', - 'LOG_NOTICE', - 'LOG_INFO', - 'LOG_DEBUG', - - 'LOG_PID', - 'LOG_CONS', - 'LOG_NDELAY', - - 'LOG_KERN', - 'LOG_USER', - 'LOG_MAIL', - 'LOG_DAEMON', - 'LOG_AUTH', - 'LOG_LPR', - 'LOG_LOCAL0', - 'LOG_LOCAL1', - 'LOG_LOCAL2', - 'LOG_LOCAL3', - 'LOG_LOCAL4', - 'LOG_LOCAL5', - 'LOG_LOCAL6', - 'LOG_LOCAL7', -) -_OPTIONAL_CONSTANTS = ( - 'LOG_NOWAIT', - 'LOG_PERROR', - - 'LOG_SYSLOG', - 'LOG_CRON', - 'LOG_UUCP', - 'LOG_NEWS', -) - -# Constant aliases if there are not defined -_ALIAS = ( - ('LOG_SYSLOG', 'LOG_DAEMON'), - ('LOG_CRON', 'LOG_DAEMON'), - ('LOG_NEWS', 'LOG_MAIL'), - ('LOG_UUCP', 'LOG_MAIL'), -) - -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) - -config = configure(SyslogConfigure) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -for alias, key in _ALIAS: - if alias in optional_constants: - continue - globals()[alias] = globals()[key] - optional_constants.append(alias) -del config # Real prototype is: # void syslog(int priority, const char *format, ...); From arigo at codespeak.net Sat Mar 6 12:30:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 12:30:22 +0100 (CET) Subject: [pypy-svn] r71851 - in pypy/branch/ctypes-configure-cache-2/ctypes_configure: . test Message-ID: <20100306113022.662E55105B@codespeak.net> Author: arigo Date: Sat Mar 6 12:30:20 2010 New Revision: 71851 Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/cbuild.py pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Log: Merge the content of branch/ctypes-configure-cache/ctypes_configure, with minor edits and a different interface. Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/cbuild.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/cbuild.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/cbuild.py Sat Mar 6 12:30:20 2010 @@ -5,7 +5,7 @@ debug = 0 -configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') +configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure-') class ExternalCompilationInfo(object): Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py Sat Mar 6 12:30:20 2010 @@ -164,7 +164,7 @@ for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigEntry): - entries.append((key, value)) + entries.append((key, value)) if entries: # can be empty if there are only CConfigSingleEntries writer = _CWriter(CConfig) @@ -201,7 +201,6 @@ writer = _CWriter(CConfig) writer.write_header() res[key] = value.question(writer.ask_gcc) - return res # ____________________________________________________________ @@ -210,7 +209,6 @@ class CConfigEntry(object): "Abstract base class." - class Struct(CConfigEntry): """An entry in a CConfig class that stands for an externally defined structure. @@ -313,7 +311,6 @@ S.__name__ = name return S - class SimpleType(CConfigEntry): """An entry in a CConfig class that stands for an externally defined simple numeric type. @@ -350,7 +347,6 @@ ctype = fixup_ctype(ctype, self.name, (size, sign)) return ctype - class ConstantInteger(CConfigEntry): """An entry in a CConfig class that stands for an externally defined integer constant. @@ -588,14 +584,42 @@ # ____________________________________________________________ +def ctypes_repr(cls): + # ctypes_configure does not support nested structs so far + # so let's ignore it + assert isinstance(cls, ctypes._SimpleCData.__class__) + return "ctypes." + cls.__name__ + def dumpcache(referencefilename, filename, config): dirname = os.path.dirname(referencefilename) filename = os.path.join(dirname, filename) f = open(filename, 'w') + print >> f, 'import ctypes' + print >> f names = config.keys() names.sort() - for name in names: - print >> f, '%s = %r' % (name, config[name]) + for key in names: + val = config[key] + if isinstance(val, (int, long)): + f.write("%s = %d\n" % (key, val)) + elif val is None: + f.write("%s = None\n" % key) + elif isinstance(val, ctypes._SimpleCData.__class__): + # a simple type + f.write("%s = %s\n" % (key, ctypes_repr(val))) + elif isinstance(val, ctypes.Structure.__class__): + f.write("class %s(ctypes.Structure):\n" % key) + f.write(" _fields_ = [\n") + for k, v in val._fields_: + f.write(" ('%s', %s),\n" % (k, ctypes_repr(v))) + f.write(" ]\n") + elif isinstance(val, (tuple, list)): + for x in val: + assert isinstance(x, (int, long, str)), \ + "lists of integers or strings only" + f.write("%s = %r\n" % (key, val)) + else: + raise NotImplementedError("Saving of %r" % (val,)) f.close() print 'Wrote %s.' % (filename,) Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Sat Mar 6 12:30:20 2010 @@ -126,6 +126,39 @@ 'ushort': ctypes.c_ushort, 'XYZZY': 42} +def test_cache(): + configdir = configure.configdir + test_h = configdir.join('test_ctypes_platform2.h') + test_h.write('#define XYZZY 42\n' + "#define large 2147483648L\n") + + class CConfig: + _compilation_info_ = ExternalCompilationInfo( + pre_include_lines = ["/* a C comment */", + "#include ", + "#include "], + include_dirs = [str(configdir)] + ) + + FILE = configure.Struct('FILE', []) + ushort = configure.SimpleType('unsigned short') + XYZZY = configure.ConstantInteger('XYZZY') + XUZ = configure.Has('XUZ') + large = configure.DefinedConstantInteger('large') + undef = configure.Defined('really_undefined') + + cachefile = configdir.join('cache') + res = configure.configure(CConfig, savecache=configdir.join('cache')) + d = {} + execfile(str(cachefile), d) + assert d['XYZZY'] == res['XYZZY'] + assert d['ushort'] == res['ushort'] + assert d['FILE']._fields_ == res['FILE']._fields_ + assert d['FILE'].__mro__[1:] == res['FILE'].__mro__[1:] + assert d['undef'] == res['undef'] + assert d['large'] == res['large'] + assert d['XUZ'] == res['XUZ'] + def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo( From arigo at codespeak.net Sat Mar 6 12:32:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 12:32:45 +0100 (CET) Subject: [pypy-svn] r71852 - pypy/branch/ctypes-configure-cache-2/ctypes_configure/test Message-ID: <20100306113245.BF73D5105C@codespeak.net> Author: arigo Date: Sat Mar 6 12:32:44 2010 New Revision: 71852 Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Log: Oups, fix the test too. Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Sat Mar 6 12:32:44 2010 @@ -147,8 +147,11 @@ large = configure.DefinedConstantInteger('large') undef = configure.Defined('really_undefined') + res = configure.configure(CConfig) + cachefile = configdir.join('cache') - res = configure.configure(CConfig, savecache=configdir.join('cache')) + configure.dumpcache('', str(cachefile), res) + d = {} execfile(str(cachefile), d) assert d['XYZZY'] == res['XYZZY'] From arigo at codespeak.net Sat Mar 6 12:37:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 12:37:31 +0100 (CET) Subject: [pypy-svn] r71853 - in pypy/branch/ctypes-configure-cache-2/ctypes_configure: . test Message-ID: <20100306113731.3F18F5105D@codespeak.net> Author: arigo Date: Sat Mar 6 12:37:29 2010 New Revision: 71853 Added: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py (contents, props changed) pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Log: Move dumpcache() to its own module. Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/configure.py Sat Mar 6 12:37:29 2010 @@ -584,47 +584,6 @@ # ____________________________________________________________ -def ctypes_repr(cls): - # ctypes_configure does not support nested structs so far - # so let's ignore it - assert isinstance(cls, ctypes._SimpleCData.__class__) - return "ctypes." + cls.__name__ - -def dumpcache(referencefilename, filename, config): - dirname = os.path.dirname(referencefilename) - filename = os.path.join(dirname, filename) - f = open(filename, 'w') - print >> f, 'import ctypes' - print >> f - names = config.keys() - names.sort() - for key in names: - val = config[key] - if isinstance(val, (int, long)): - f.write("%s = %d\n" % (key, val)) - elif val is None: - f.write("%s = None\n" % key) - elif isinstance(val, ctypes._SimpleCData.__class__): - # a simple type - f.write("%s = %s\n" % (key, ctypes_repr(val))) - elif isinstance(val, ctypes.Structure.__class__): - f.write("class %s(ctypes.Structure):\n" % key) - f.write(" _fields_ = [\n") - for k, v in val._fields_: - f.write(" ('%s', %s),\n" % (k, ctypes_repr(v))) - f.write(" ]\n") - elif isinstance(val, (tuple, list)): - for x in val: - assert isinstance(x, (int, long, str)), \ - "lists of integers or strings only" - f.write("%s = %r\n" % (key, val)) - else: - raise NotImplementedError("Saving of %r" % (val,)) - f.close() - print 'Wrote %s.' % (filename,) - -# ____________________________________________________________ - def get_python_include_dir(): from distutils import sysconfig gcv = sysconfig.get_config_vars() Added: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py Sat Mar 6 12:37:29 2010 @@ -0,0 +1,42 @@ +import os +import ctypes + + +def dumpcache(referencefilename, filename, config): + dirname = os.path.dirname(referencefilename) + filename = os.path.join(dirname, filename) + f = open(filename, 'w') + print >> f, 'import ctypes' + print >> f + names = config.keys() + names.sort() + for key in names: + val = config[key] + if isinstance(val, (int, long)): + f.write("%s = %d\n" % (key, val)) + elif val is None: + f.write("%s = None\n" % key) + elif isinstance(val, ctypes._SimpleCData.__class__): + # a simple type + f.write("%s = %s\n" % (key, ctypes_repr(val))) + elif isinstance(val, ctypes.Structure.__class__): + f.write("class %s(ctypes.Structure):\n" % key) + f.write(" _fields_ = [\n") + for k, v in val._fields_: + f.write(" ('%s', %s),\n" % (k, ctypes_repr(v))) + f.write(" ]\n") + elif isinstance(val, (tuple, list)): + for x in val: + assert isinstance(x, (int, long, str)), \ + "lists of integers or strings only" + f.write("%s = %r\n" % (key, val)) + else: + raise NotImplementedError("Saving of %r" % (val,)) + f.close() + print 'Wrote %s.' % (filename,) + +def ctypes_repr(cls): + # ctypes_configure does not support nested structs so far + # so let's ignore it + assert isinstance(cls, ctypes._SimpleCData.__class__) + return "ctypes." + cls.__name__ Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_configure.py Sat Mar 6 12:37:29 2010 @@ -126,42 +126,6 @@ 'ushort': ctypes.c_ushort, 'XYZZY': 42} -def test_cache(): - configdir = configure.configdir - test_h = configdir.join('test_ctypes_platform2.h') - test_h.write('#define XYZZY 42\n' - "#define large 2147483648L\n") - - class CConfig: - _compilation_info_ = ExternalCompilationInfo( - pre_include_lines = ["/* a C comment */", - "#include ", - "#include "], - include_dirs = [str(configdir)] - ) - - FILE = configure.Struct('FILE', []) - ushort = configure.SimpleType('unsigned short') - XYZZY = configure.ConstantInteger('XYZZY') - XUZ = configure.Has('XUZ') - large = configure.DefinedConstantInteger('large') - undef = configure.Defined('really_undefined') - - res = configure.configure(CConfig) - - cachefile = configdir.join('cache') - configure.dumpcache('', str(cachefile), res) - - d = {} - execfile(str(cachefile), d) - assert d['XYZZY'] == res['XYZZY'] - assert d['ushort'] == res['ushort'] - assert d['FILE']._fields_ == res['FILE']._fields_ - assert d['FILE'].__mro__[1:] == res['FILE'].__mro__[1:] - assert d['undef'] == res['undef'] - assert d['large'] == res['large'] - assert d['XUZ'] == res['XUZ'] - def test_ifdef(): class CConfig: _compilation_info_ = ExternalCompilationInfo( Added: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py Sat Mar 6 12:37:29 2010 @@ -0,0 +1,39 @@ +from ctypes_configure import configure, dumpcache +from ctypes_configure.cbuild import ExternalCompilationInfo + + +def test_cache(): + configdir = configure.configdir + test_h = configdir.join('test_ctypes_platform2.h') + test_h.write('#define XYZZY 42\n' + "#define large 2147483648L\n") + + class CConfig: + _compilation_info_ = ExternalCompilationInfo( + pre_include_lines = ["/* a C comment */", + "#include ", + "#include "], + include_dirs = [str(configdir)] + ) + + FILE = configure.Struct('FILE', []) + ushort = configure.SimpleType('unsigned short') + XYZZY = configure.ConstantInteger('XYZZY') + XUZ = configure.Has('XUZ') + large = configure.DefinedConstantInteger('large') + undef = configure.Defined('really_undefined') + + res = configure.configure(CConfig) + + cachefile = configdir.join('cache') + dumpcache.dumpcache('', str(cachefile), res) + + d = {} + execfile(str(cachefile), d) + assert d['XYZZY'] == res['XYZZY'] + assert d['ushort'] == res['ushort'] + assert d['FILE']._fields_ == res['FILE']._fields_ + assert d['FILE'].__mro__[1:] == res['FILE'].__mro__[1:] + assert d['undef'] == res['undef'] + assert d['large'] == res['large'] + assert d['XUZ'] == res['XUZ'] From arigo at codespeak.net Sat Mar 6 12:49:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 12:49:52 +0100 (CET) Subject: [pypy-svn] r71854 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . ctypes_config_cache ctypes_config_cache/test Message-ID: <20100306114952.7C5AD5105E@codespeak.net> Author: arigo Date: Sat Mar 6 12:49:51 2010 New Revision: 71854 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/hashlib.ctc.py (contents, props changed) pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/ (props changed) pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_hashlib.py pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py Log: Add hashlib.ctc.py, and write tests for *.ctc.py. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_hashlib.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/_hashlib.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/_hashlib.py Sat Mar 6 12:49:51 2010 @@ -1,6 +1,8 @@ from ctypes import * import ctypes.util -from ctypes_configure import configure + +# load the platform-specific cache made by running hashlib.ctc.py +from ctypes_config_cache._hashlib_cache import * # Note: OpenSSL on OS X only provides md5 and sha1 libpath = ctypes.util.find_library('ssl') @@ -16,18 +18,6 @@ else: return buffer(x)[:] -class CConfig: - _compilation_info_ = configure.ExternalCompilationInfo( - includes=['openssl/evp.h'], - ) - EVP_MD = configure.Struct('EVP_MD', - []) - EVP_MD_CTX = configure.Struct('EVP_MD_CTX', - [('digest', c_void_p)]) -c = configure.configure(CConfig) -EVP_MD_CTX = c['EVP_MD_CTX'] -EVP_MD = c['EVP_MD'] - def patch_fields(fields): res = [] for k, v in fields: @@ -39,7 +29,6 @@ class EVP_MD_CTX(Structure): _fields_ = patch_fields(EVP_MD_CTX._fields_) -del c # OpenSSL initialization lib.OpenSSL_add_all_digests() Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/hashlib.ctc.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/hashlib.ctc.py Sat Mar 6 12:49:51 2010 @@ -0,0 +1,21 @@ +""" +'ctypes_configure' source for _hashlib.py. +Run this to rebuild _hashlib_cache.py. +""" + +import autopath +from ctypes import * +from ctypes_configure import configure, dumpcache + + +class CConfig: + _compilation_info_ = configure.ExternalCompilationInfo( + includes=['openssl/evp.h'], + ) + EVP_MD = configure.Struct('EVP_MD', + []) + EVP_MD_CTX = configure.Struct('EVP_MD_CTX', + [('digest', c_void_p)]) + +config = configure.configure(CConfig) +dumpcache.dumpcache(__file__, '_hashlib_cache.py', config) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py Sat Mar 6 12:49:51 2010 @@ -4,8 +4,9 @@ """ import autopath -from ctypes_configure.configure import (configure, dumpcache, +from ctypes_configure.configure import (configure, ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) +from ctypes_configure.dumpcache import dumpcache _CONSTANTS = ( Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py Sat Mar 6 12:49:51 2010 @@ -0,0 +1,32 @@ +import py +import sys, os +from pypy.tool.udir import udir + +dirpath = py.path.local(__file__).dirpath().dirpath() + + +def run(filename, outputname): + filepath = dirpath.join(filename) + tmpdir = udir.ensure('testcache-' + filename, dir=True) + outputpath = tmpdir.join(outputname) + d = {'__file__': str(outputpath)} + path = sys.path[:] + try: + sys.path.insert(0, str(dirpath)) + execfile(str(filepath), d) + finally: + sys.path[:] = path + # + assert outputpath.check(exists=1) + d = {} + execfile(str(outputpath), d) + return d + + +def test_syslog(): + d = run('syslog.ctc.py', '_syslog_cache.py') + assert 'LOG_NOTICE' in d + +def test_hashlib(): + d = run('hashlib.ctc.py', '_hashlib_cache.py') + assert hasattr(d['EVP_MD_CTX'], 'digest') From arigo at codespeak.net Sat Mar 6 13:01:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:01:31 +0100 (CET) Subject: [pypy-svn] r71855 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . ctypes_config_cache Message-ID: <20100306120131.493855105F@codespeak.net> Author: arigo Date: Sat Mar 6 13:01:29 2010 New Revision: 71855 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py Log: Split _locale.py. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py Sat Mar 6 13:01:29 2010 @@ -7,48 +7,16 @@ c_ubyte, c_int, c_char_p, c_wchar_p) from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno -from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + +# load the platform-specific cache made by running locale.ctc.py +from ctypes_config_cache._locale_cache import * + size_t = c_int # XXX check where this comes from CHAR_MAX = 127 -_CONSTANTS = ( - 'LC_CTYPE', - 'LC_NUMERIC', - 'LC_TIME', - 'LC_COLLATE', - 'LC_MONETARY', - 'LC_MESSAGES', - 'LC_ALL', - 'LC_PAPER', - 'LC_NAME', - 'LC_ADDRESS', - 'LC_TELEPHONE', - 'LC_MEASUREMENT', - 'LC_IDENTIFICATION', -) - -class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) -for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) - -try: - locale_config = configure(LocaleConfigure, noerr=True) -except Exception, e: - # should probably be moved into configure() - # as an optional feature - raise ImportError("%s: %s" % (e.__class__, e)) - -for key in _CONSTANTS: - globals()[key] = locale_config[key] -del LocaleConfigure -del locale_config - -HAS_LANGINFO = True # Ubuntu Gusty i386 structure class lconv(Structure): @@ -288,29 +256,6 @@ raise NotImplementedError() if HAS_LANGINFO: - # this is incomplete list - langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' - 'YESEXPR NOEXPR CRNCYSTR').split(" ") - for i in range(1, 8): - langinfo_names.append("DAY_%d" % i) - langinfo_names.append("ABDAY_%d" % i) - for i in range(1, 13): - langinfo_names.append("MON_%d" % i) - langinfo_names.append("ABMON_%d" % i) - - class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) - nl_item = SimpleType('nl_item') - for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) - - config = configure(LanginfoConfigure) - nl_item = config['nl_item'] - for key in langinfo_names: - globals()[key] = config[key] - del LanginfoConfigure - del config - _nl_langinfo = libc.nl_langinfo _nl_langinfo.argtypes = (nl_item,) _nl_langinfo.restype = c_char_p Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py Sat Mar 6 13:01:29 2010 @@ -0,0 +1,63 @@ +""" +'ctypes_configure' source for _locale.py. +Run this to rebuild _locale_cache.py. +""" + +import autopath +from ctypes_configure.configure import (configure, ExternalCompilationInfo, + ConstantInteger, DefinedConstantInteger, SimpleType) +from ctypes_configure.dumpcache import dumpcache + +# ____________________________________________________________ + +_CONSTANTS = [ + 'LC_CTYPE', + 'LC_NUMERIC', + 'LC_TIME', + 'LC_COLLATE', + 'LC_MONETARY', + 'LC_MESSAGES', + 'LC_ALL', + 'LC_PAPER', + 'LC_NAME', + 'LC_ADDRESS', + 'LC_TELEPHONE', + 'LC_MEASUREMENT', + 'LC_IDENTIFICATION', +] + +class LocaleConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) +for key in _CONSTANTS: + setattr(LocaleConfigure, key, ConstantInteger(key)) + +config = configure(LocaleConfigure, noerr=True) + +# ____________________________________________________________ + +HAS_LANGINFO = True # xxx hard-coded to True for now + +if HAS_LANGINFO: + # this is incomplete list + langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' + 'YESEXPR NOEXPR CRNCYSTR').split(" ") + for i in range(1, 8): + langinfo_names.append("DAY_%d" % i) + langinfo_names.append("ABDAY_%d" % i) + for i in range(1, 13): + langinfo_names.append("MON_%d" % i) + langinfo_names.append("ABMON_%d" % i) + + class LanginfoConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) + nl_item = SimpleType('nl_item') + for key in langinfo_names: + setattr(LanginfoConfigure, key, ConstantInteger(key)) + + config.update(configure(LanginfoConfigure)) + +# ____________________________________________________________ + +config['_CONSTANTS'] = _CONSTANTS +config['HAS_LANGINFO'] = HAS_LANGINFO +dumpcache(__file__, '_locale_cache.py', config) From arigo at codespeak.net Sat Mar 6 13:10:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:10:03 +0100 (CET) Subject: [pypy-svn] r71856 - pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test Message-ID: <20100306121003.010F95105F@codespeak.net> Author: arigo Date: Sat Mar 6 13:10:01 2010 New Revision: 71856 Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py Log: Fix test_locale to actually test our implementation, not CPython's. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py Sat Mar 6 13:10:01 2010 @@ -1,5 +1,5 @@ import py -import locale +from pypy.lib import _locale import sys def setup_module(mod): @@ -8,7 +8,7 @@ class TestLocale: def setup_class(cls): - cls.oldlocale = locale.setlocale(locale.LC_NUMERIC) + cls.oldlocale = _locale.setlocale(_locale.LC_NUMERIC) if sys.platform.startswith("win"): cls.tloc = "en" elif sys.platform.startswith("freebsd"): @@ -16,14 +16,15 @@ else: cls.tloc = "en_US.UTF8" try: - locale.setlocale(locale.LC_NUMERIC, cls.tloc) - except locale.Error: + _locale.setlocale(_locale.LC_NUMERIC, cls.tloc) + except _locale.Error: py.test.skip("test locale %s not supported" % cls.tloc) def teardown_class(cls): - locale.setlocale(locale.LC_NUMERIC, cls.oldlocale) + _locale.setlocale(_locale.LC_NUMERIC, cls.oldlocale) def test_format(self): + py.test.skip("XXX fix or kill me") def testformat(formatstr, value, grouping = 0, output=None): if output: @@ -41,8 +42,11 @@ testformat("%20.f", -42, grouping=1, output=' -42') testformat("%+10.f", -4200, grouping=1, output=' -4,200') testformat("%-10.f", 4200, grouping=1, output='4,200 ') - # Invoke getpreferredencoding to make sure it does not cause exceptions, - locale.getpreferredencoding() + + def test_getpreferredencoding(self): + py.test.skip("XXX fix or kill me") + # Invoke getpreferredencoding to make sure it does not cause exceptions + _locale.getpreferredencoding() # Test BSD Rune locale's bug for isctype functions. def test_bsd_bug(self): @@ -51,8 +55,8 @@ result = getattr(s, method)() assert result == output - oldlocale = locale.setlocale(locale.LC_CTYPE) - locale.setlocale(locale.LC_CTYPE, self.tloc) + oldlocale = _locale.setlocale(_locale.LC_CTYPE) + _locale.setlocale(_locale.LC_CTYPE, self.tloc) try: teststrop('\x20', 'isspace', True) teststrop('\xa0', 'isspace', False) @@ -66,4 +70,4 @@ teststrop('\xcc\x85', 'lower', '\xcc\x85') teststrop('\xed\x95\xa0', 'upper', '\xed\x95\xa0') finally: - locale.setlocale(locale.LC_CTYPE, oldlocale) + _locale.setlocale(_locale.LC_CTYPE, oldlocale) From arigo at codespeak.net Sat Mar 6 13:10:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:10:33 +0100 (CET) Subject: [pypy-svn] r71857 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . ctypes_config_cache Message-ID: <20100306121033.4DCE35105F@codespeak.net> Author: arigo Date: Sat Mar 6 13:10:31 2010 New Revision: 71857 Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py Log: Fixes found by the previous test fix. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/_locale.py Sat Mar 6 13:10:31 2010 @@ -314,9 +314,8 @@ 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', 'bindtextdomain', 'CHAR_MAX', -) + _CONSTANTS + tuple(langinfo_names) +) + ALL_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: __all__ += ('nl_langinfo',) - Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/locale.ctc.py Sat Mar 6 13:10:31 2010 @@ -10,7 +10,7 @@ # ____________________________________________________________ -_CONSTANTS = [ +_CONSTANTS = ( 'LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', @@ -24,7 +24,7 @@ 'LC_TELEPHONE', 'LC_MEASUREMENT', 'LC_IDENTIFICATION', -] +) class LocaleConfigure: _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) @@ -55,9 +55,10 @@ setattr(LanginfoConfigure, key, ConstantInteger(key)) config.update(configure(LanginfoConfigure)) + _CONSTANTS = _CONSTANTS + tuple(langinfo_names) # ____________________________________________________________ -config['_CONSTANTS'] = _CONSTANTS +config['ALL_CONSTANTS'] = _CONSTANTS config['HAS_LANGINFO'] = HAS_LANGINFO dumpcache(__file__, '_locale_cache.py', config) From arigo at codespeak.net Sat Mar 6 13:17:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:17:50 +0100 (CET) Subject: [pypy-svn] r71858 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . ctypes_config_cache Message-ID: <20100306121750.B03275105A@codespeak.net> Author: arigo Date: Sat Mar 6 13:17:49 2010 New Revision: 71858 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/resource.ctc.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/resource.py Log: Update resource.py. Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/resource.ctc.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/resource.ctc.py Sat Mar 6 13:17:49 2010 @@ -0,0 +1,63 @@ +""" +'ctypes_configure' source for resource.py. +Run this to rebuild _resource_cache.py. +""" + +import autopath + +from ctypes import sizeof +from ctypes_configure.dumpcache import dumpcache +from ctypes_configure.configure import (configure, + ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, + SimpleType) + + +_CONSTANTS = ( + 'RLIM_INFINITY', + 'RLIM_NLIMITS', +) +_OPTIONAL_CONSTANTS = ( + 'RLIMIT_CPU', + 'RLIMIT_FSIZE', + 'RLIMIT_DATA', + 'RLIMIT_STACK', + 'RLIMIT_CORE', + 'RLIMIT_RSS', + 'RLIMIT_NPROC', + 'RLIMIT_NOFILE', + 'RLIMIT_OFILE', + 'RLIMIT_MEMLOCK', + 'RLIMIT_AS', + 'RLIMIT_LOCKS', + 'RLIMIT_SIGPENDING', + 'RLIMIT_MSGQUEUE', + 'RLIMIT_NICE', + 'RLIMIT_RTPRIO', + 'RLIMIT_VMEM', + + 'RUSAGE_BOTH', + 'RUSAGE_SELF', + 'RUSAGE_CHILDREN', +) + +# Setup our configure +class ResourceConfigure: + _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) + rlim_t = SimpleType('rlim_t') +for key in _CONSTANTS: + setattr(ResourceConfigure, key, ConstantInteger(key)) +for key in _OPTIONAL_CONSTANTS: + setattr(ResourceConfigure, key, DefinedConstantInteger(key)) + +# Configure constants and types +config = configure(ResourceConfigure) +config['rlim_t_max'] = (1<<(sizeof(config['rlim_t']) * 8)) - 1 +optional_constants = [] +for key in _OPTIONAL_CONSTANTS: + if config[key] is not None: + optional_constants.append(key) + else: + del config[key] + +config['ALL_CONSTANTS'] = _CONSTANTS + tuple(optional_constants) +dumpcache(__file__, '_resource_cache.py', config) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/resource.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/resource.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/resource.py Sat Mar 6 13:17:49 2010 @@ -2,45 +2,18 @@ if sys.platform == 'win32': raise ImportError('resource module not available for win32') +# load the platform-specific cache made by running resource.ctc.py +from ctypes_config_cache._resource_cache import * + from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno from ctypes import Structure, c_int, c_long, byref, sizeof from errno import EINVAL, EPERM -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, - SimpleType) import _structseq class error(Exception): pass -_CONSTANTS = ( - 'RLIM_INFINITY', - 'RLIM_NLIMITS', -) -_OPTIONAL_CONSTANTS = ( - 'RLIMIT_CPU', - 'RLIMIT_FSIZE', - 'RLIMIT_DATA', - 'RLIMIT_STACK', - 'RLIMIT_CORE', - 'RLIMIT_RSS', - 'RLIMIT_NPROC', - 'RLIMIT_NOFILE', - 'RLIMIT_OFILE', - 'RLIMIT_MEMLOCK', - 'RLIMIT_AS', - 'RLIMIT_LOCKS', - 'RLIMIT_SIGPENDING', - 'RLIMIT_MSGQUEUE', - 'RLIMIT_NICE', - 'RLIMIT_RTPRIO', - 'RLIMIT_VMEM', - - 'RUSAGE_BOTH', - 'RUSAGE_SELF', - 'RUSAGE_CHILDREN', -) # Read required libc functions _getrusage = libc.getrusage @@ -52,27 +25,6 @@ from os import sysconf _getpagesize = None -# Setup our configure -class ResourceConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) - rlim_t = SimpleType('rlim_t') -for key in _CONSTANTS: - setattr(ResourceConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(ResourceConfigure, key, DefinedConstantInteger(key)) - -# Configure constants and types -config = configure(ResourceConfigure) -rlim_t = config['rlim_t'] -sizeof_rlim_t = 1<<(sizeof(rlim_t) * 8) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -del config class timeval(Structure): _fields_ = ( @@ -126,9 +78,9 @@ ru_nivcsw = _structseq.structseqfield(15) def rlimit_check_bounds(rlim_cur, rlim_max): - if rlim_cur > sizeof_rlim_t: + if rlim_cur > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_cur) - if rlim_max > sizeof_rlim_t: + if rlim_max > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_max) class rlimit(Structure): @@ -202,10 +154,9 @@ # Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE return sysconf("SC_PAGESIZE") -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'error', 'timeval', 'struct_rusage', 'rlimit', 'getrusage', 'getrlimit', 'setrlimit', 'getpagesize', ) -del optional_constants - +del ALL_CONSTANTS From arigo at codespeak.net Sat Mar 6 13:29:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:29:52 +0100 (CET) Subject: [pypy-svn] r71859 - in pypy/branch/ctypes-configure-cache-2/pypy: lib/app_test lib/ctypes_config_cache translator/goal Message-ID: <20100306122952.77C3851058@codespeak.net> Author: arigo Date: Sat Mar 6 13:29:50 2010 New Revision: 71859 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_hashlib.py pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_resource.py pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Log: A tool to call all .ctc.py files to force a rebuild. Call it in the respective tests and at the start of a translation. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_hashlib.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_hashlib.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_hashlib.py Sat Mar 6 13:29:50 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('hashlib.ctc.py') + from pypy.lib import hashlib, _hashlib def test_unicode(): Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_locale.py Sat Mar 6 13:29:50 2010 @@ -1,7 +1,12 @@ import py -from pypy.lib import _locale import sys +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('locale.ctc.py') + +from pypy.lib import _locale + + def setup_module(mod): if sys.platform == 'darwin': py.test.skip("Locale support on MacOSX is minimal and cannot be tested") Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_resource.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_resource.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_resource.py Sat Mar 6 13:29:50 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('resource.ctc.py') + from pypy.lib import resource def test_resource(): Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py Sat Mar 6 13:29:50 2010 @@ -0,0 +1,27 @@ +#! /usr/bin/env python +# Run this script to rebuild all caches from the *.ctc.py files. + +import autopath +import os, sys + +_dirpath = os.path.dirname(__file__) + + +def rebuild_one(name): + filename = os.path.join(_dirpath, name) + d = {'__file__': filename} + path = sys.path[:] + try: + sys.path.insert(0, _dirpath) + execfile(filename, d) + finally: + sys.path[:] = path + +def rebuild(): + for p in os.listdir(_dirpath): + if p.endswith('.ctc.py'): + rebuild_one(p) + + +if __name__ == '__main__': + rebuild() Modified: pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Sat Mar 6 13:29:50 2010 @@ -216,6 +216,9 @@ return PyPyJitPolicy() def get_entry_point(self, config): + from pypy.lib.ctypes_config_cache import rebuild + rebuild.rebuild() + space = make_objspace(config) # manually imports app_main.py From arigo at codespeak.net Sat Mar 6 13:43:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:43:11 +0100 (CET) Subject: [pypy-svn] r71860 - in pypy/branch/ctypes-configure-cache-2/ctypes_configure: . test Message-ID: <20100306124311.EA3B551058@codespeak.net> Author: arigo Date: Sat Mar 6 13:43:10 2010 New Revision: 71860 Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py Log: Support simple arrays, like "c_int*5". Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py Sat Mar 6 13:43:10 2010 @@ -16,9 +16,6 @@ f.write("%s = %d\n" % (key, val)) elif val is None: f.write("%s = None\n" % key) - elif isinstance(val, ctypes._SimpleCData.__class__): - # a simple type - f.write("%s = %s\n" % (key, ctypes_repr(val))) elif isinstance(val, ctypes.Structure.__class__): f.write("class %s(ctypes.Structure):\n" % key) f.write(" _fields_ = [\n") @@ -31,12 +28,16 @@ "lists of integers or strings only" f.write("%s = %r\n" % (key, val)) else: - raise NotImplementedError("Saving of %r" % (val,)) + # a simple type, hopefully + f.write("%s = %s\n" % (key, ctypes_repr(val))) f.close() print 'Wrote %s.' % (filename,) def ctypes_repr(cls): # ctypes_configure does not support nested structs so far # so let's ignore it - assert isinstance(cls, ctypes._SimpleCData.__class__) - return "ctypes." + cls.__name__ + if isinstance(cls, ctypes._SimpleCData.__class__): + return "ctypes." + cls.__name__ + if hasattr(cls, '_length_') and hasattr(cls, '_type_'): # assume an array + return '%d * %s' % (cls._length_, ctypes_repr(cls._type_)) + raise NotImplementedError("saving of object with type %r" % type(cls)) Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py Sat Mar 6 13:43:10 2010 @@ -1,3 +1,4 @@ +import ctypes from ctypes_configure import configure, dumpcache from ctypes_configure.cbuild import ExternalCompilationInfo @@ -37,3 +38,14 @@ assert d['undef'] == res['undef'] assert d['large'] == res['large'] assert d['XUZ'] == res['XUZ'] + + +def test_cache_array(): + configdir = configure.configdir + res = {'foo': ctypes.c_short * 27} + cachefile = configdir.join('cache_array') + dumpcache.dumpcache('', str(cachefile), res) + # + d = {} + execfile(str(cachefile), d) + assert d['foo'] == res['foo'] From arigo at codespeak.net Sat Mar 6 13:44:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:44:43 +0100 (CET) Subject: [pypy-svn] r71861 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . app_test ctypes_config_cache ctypes_config_cache/test Message-ID: <20100306124443.9B60F51058@codespeak.net> Author: arigo Date: Sat Mar 6 13:44:41 2010 New Revision: 71861 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/pyexpat.ctc.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_pyexpat.py pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py pypy/branch/ctypes-configure-cache-2/pypy/lib/pyexpat.py Log: Update pyexpat. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_pyexpat.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_pyexpat.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_pyexpat.py Sat Mar 6 13:44:41 2010 @@ -4,6 +4,9 @@ import StringIO, sys import unittest, py +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('pyexpat.ctc.py') + from pypy.lib import pyexpat #from xml.parsers import expat expat = pyexpat Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/pyexpat.ctc.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/pyexpat.ctc.py Sat Mar 6 13:44:41 2010 @@ -0,0 +1,45 @@ +""" +'ctypes_configure' source for pyexpat.py. +Run this to rebuild _pyexpat_cache.py. +""" + +import autopath +import ctypes +from ctypes import c_char_p, c_int, c_void_p, c_char +from ctypes_configure import configure, dumpcache + + +class CConfigure: + _compilation_info_ = configure.ExternalCompilationInfo( + includes = ['expat.h'], + libraries = ['expat'], + pre_include_lines = [ + '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], + ) + + XML_Char = configure.SimpleType('XML_Char', c_char) + XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') + for name in ['XML_PARAM_ENTITY_PARSING_NEVER', + 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', + 'XML_PARAM_ENTITY_PARSING_ALWAYS']: + locals()[name] = configure.ConstantInteger(name) + + XML_Encoding = configure.Struct('XML_Encoding',[ + ('data', c_void_p), + ('convert', c_void_p), + ('release', c_void_p), + ('map', c_int * 256)]) + XML_Content = configure.Struct('XML_Content',[ + ('numchildren', c_int), + ('children', c_void_p), + ('name', c_char_p), + ('type', c_int), + ('quant', c_int), + ]) + # this is insanely stupid + XML_FALSE = configure.ConstantInteger('XML_FALSE') + XML_TRUE = configure.ConstantInteger('XML_TRUE') + +config = configure.configure(CConfigure) + +dumpcache.dumpcache(__file__, '_pyexpat_cache.py', config) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/test/test_cache.py Sat Mar 6 13:44:41 2010 @@ -30,3 +30,11 @@ def test_hashlib(): d = run('hashlib.ctc.py', '_hashlib_cache.py') assert hasattr(d['EVP_MD_CTX'], 'digest') + +def test_resource(): + d = run('resource.ctc.py', '_resource_cache.py') + assert 'RLIM_NLIMITS' in d + +def test_pyexpat(): + d = run('pyexpat.ctc.py', '_pyexpat_cache.py') + assert 'XML_COMBINED_VERSION' in d Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/pyexpat.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/pyexpat.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/pyexpat.py Sat Mar 6 13:44:41 2010 @@ -1,46 +1,15 @@ import ctypes import ctypes.util -from ctypes_configure import configure from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p import sys +# load the platform-specific cache made by running pyexpat.ctc.py +from ctypes_config_cache._pyexpat_cache import * + + lib = ctypes.CDLL(ctypes.util.find_library('expat')) -class CConfigure: - _compilation_info_ = configure.ExternalCompilationInfo( - includes = ['expat.h'], - libraries = ['expat'], - pre_include_lines = [ - '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], - ) - - XML_Char = configure.SimpleType('XML_Char', ctypes.c_char) - XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') - for name in ['XML_PARAM_ENTITY_PARSING_NEVER', - 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', - 'XML_PARAM_ENTITY_PARSING_ALWAYS']: - locals()[name] = configure.ConstantInteger(name) - - XML_Encoding = configure.Struct('XML_Encoding',[ - ('data', c_void_p), - ('convert', c_void_p), - ('release', c_void_p), - ('map', c_int * 256)]) - XML_Content = configure.Struct('XML_Content',[ - ('numchildren', c_int), - ('children', c_void_p), - ('name', c_char_p), - ('type', c_int), - ('quant', c_int), - ]) - # this is insanely stupid - XML_FALSE = configure.ConstantInteger('XML_FALSE') - XML_TRUE = configure.ConstantInteger('XML_TRUE') - -info = configure.configure(CConfigure) -for k, v in info.items(): - globals()[k] = v XML_Content.children = POINTER(XML_Content) XML_Parser = ctypes.c_void_p # an opaque pointer From arigo at codespeak.net Sat Mar 6 13:58:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 13:58:33 +0100 (CET) Subject: [pypy-svn] r71862 - in pypy/branch/ctypes-configure-cache-2/ctypes_configure: . test Message-ID: <20100306125833.1ED6051058@codespeak.net> Author: arigo Date: Sat Mar 6 13:58:27 2010 New Revision: 71862 Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py Log: Write the multiplication in the other order. Fixes an obscure test (it would be ok for this test to fail, but not give a wrong result). Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py Sat Mar 6 13:58:27 2010 @@ -39,5 +39,5 @@ if isinstance(cls, ctypes._SimpleCData.__class__): return "ctypes." + cls.__name__ if hasattr(cls, '_length_') and hasattr(cls, '_type_'): # assume an array - return '%d * %s' % (cls._length_, ctypes_repr(cls._type_)) + return '%s*%d' % (ctypes_repr(cls._type_), cls._length_) raise NotImplementedError("saving of object with type %r" % type(cls)) Modified: pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py (original) +++ pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py Sat Mar 6 13:58:27 2010 @@ -49,3 +49,13 @@ d = {} execfile(str(cachefile), d) assert d['foo'] == res['foo'] + +def test_cache_array_array(): + configdir = configure.configdir + res = {'foo': (ctypes.c_int * 2) * 3} + cachefile = configdir.join('cache_array_array') + dumpcache.dumpcache('', str(cachefile), res) + # + d = {} + execfile(str(cachefile), d) + assert d['foo'] == res['foo'] From arigo at codespeak.net Sat Mar 6 14:10:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 14:10:40 +0100 (CET) Subject: [pypy-svn] r71863 - in pypy/branch/ctypes-configure-cache-2/pypy: lib/ctypes_config_cache translator/goal Message-ID: <20100306131040.28A8A51058@codespeak.net> Author: arigo Date: Sat Mar 6 14:10:38 2010 New Revision: 71863 Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Log: Pass a log file in which to report errors, but don't stop. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py Sat Mar 6 14:10:38 2010 @@ -17,10 +17,18 @@ finally: sys.path[:] = path -def rebuild(): +def rebuild(log=None): for p in os.listdir(_dirpath): if p.endswith('.ctc.py'): - rebuild_one(p) + try: + rebuild_one(p) + except Exception, e: + if log is None: + raise + else: + log.ERROR("Running %s:\n %s: %s" % ( + os.path.join(_dirpath, p), + e.__class__.__name__, e)) if __name__ == '__main__': Modified: pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Sat Mar 6 14:10:38 2010 @@ -217,7 +217,8 @@ def get_entry_point(self, config): from pypy.lib.ctypes_config_cache import rebuild - rebuild.rebuild() + import translate + rebuild.rebuild(translate.log) space = make_objspace(config) From arigo at codespeak.net Sat Mar 6 14:16:28 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 14:16:28 +0100 (CET) Subject: [pypy-svn] r71864 - in pypy/branch/ctypes-configure-cache-2/pypy: lib/ctypes_config_cache translator/goal Message-ID: <20100306131628.215C451058@codespeak.net> Author: arigo Date: Sat Mar 6 14:16:27 2010 New Revision: 71864 Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Log: Tweaks. Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py Sat Mar 6 14:16:27 2010 @@ -3,9 +3,14 @@ import autopath import os, sys +import py _dirpath = os.path.dirname(__file__) +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("ctypes_config_cache") +py.log.setconsumer("ctypes_config_cache", ansi_log) + def rebuild_one(name): filename = os.path.join(_dirpath, name) @@ -17,19 +22,20 @@ finally: sys.path[:] = path -def rebuild(log=None): +def try_rebuild(): + for p in os.listdir(_dirpath): + if p.startswith('_') and (p.endswith('_cache.py') or + p.endswith('_cache.pyc')): + os.unlink(os.path.join(_dirpath, p)) for p in os.listdir(_dirpath): if p.endswith('.ctc.py'): try: rebuild_one(p) except Exception, e: - if log is None: - raise - else: - log.ERROR("Running %s:\n %s: %s" % ( - os.path.join(_dirpath, p), - e.__class__.__name__, e)) + log.ERROR("Running %s:\n %s: %s" % ( + os.path.join(_dirpath, p), + e.__class__.__name__, e)) if __name__ == '__main__': - rebuild() + try_rebuild() Modified: pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/translator/goal/targetpypystandalone.py Sat Mar 6 14:16:27 2010 @@ -217,8 +217,7 @@ def get_entry_point(self, config): from pypy.lib.ctypes_config_cache import rebuild - import translate - rebuild.rebuild(translate.log) + rebuild.try_rebuild() space = make_objspace(config) From arigo at codespeak.net Sat Mar 6 14:22:28 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Mar 2010 14:22:28 +0100 (CET) Subject: [pypy-svn] r71865 - in pypy/branch/ctypes-configure-cache-2/pypy/lib: . app_test ctypes_config_cache Message-ID: <20100306132228.1ACCE51058@codespeak.net> Author: arigo Date: Sat Mar 6 14:22:27 2010 New Revision: 71865 Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_syslog.py (contents, props changed) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py Log: Test and fix. Added: pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_syslog.py ============================================================================== --- (empty file) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_syslog.py Sat Mar 6 14:22:27 2010 @@ -0,0 +1,11 @@ + +# XXX very minimal test + +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('syslog.ctc.py') + +from pypy.lib import syslog + + +def test_syslog(): + assert hasattr(syslog, 'LOG_ALERT') Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/syslog.ctc.py Sat Mar 6 14:22:27 2010 @@ -64,17 +64,13 @@ setattr(SyslogConfigure, key, DefinedConstantInteger(key)) config = configure(SyslogConfigure) -optional_constants = [] for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - optional_constants.append(key) - else: + if config[key] is None: del config[key] for alias, key in _ALIAS: - if alias in optional_constants: - continue - config[alias] = config[key] - optional_constants.append(alias) + config.setdefault(alias, config[key]) -config['optional_constants'] = optional_constants +all_constants = config.keys() +all_constants.sort() +config['ALL_CONSTANTS'] = tuple(all_constants) dumpcache(__file__, '_syslog_cache.py', config) Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/syslog.py Sat Mar 6 14:22:27 2010 @@ -56,9 +56,8 @@ def LOG_UPTO(pri): return (1 << (pri + 1)) - 1 -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'openlog', 'syslog', 'closelog', 'setlogmask', 'LOG_MASK', 'LOG_UPTO') -del optional_constants - +del ALL_CONSTANTS From fijal at codespeak.net Sat Mar 6 18:13:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 6 Mar 2010 18:13:39 +0100 (CET) Subject: [pypy-svn] r71867 - pypy/benchmarks Message-ID: <20100306171339.C38EC51058@codespeak.net> Author: fijal Date: Sat Mar 6 18:13:37 2010 New Revision: 71867 Modified: pypy/benchmarks/benchmarks.py Log: Fix the scaling of iterations to previous number Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Sat Mar 6 18:13:37 2010 @@ -23,6 +23,8 @@ number = float(line.split(" ")[0]) if name == 'tcp': return 100*1024*1024/number + elif name == 'iteration': + return 10000/number else: return 100/number bm_path = relative('own', 'twisted', name + '.py') From dan at codespeak.net Sat Mar 6 21:03:17 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 6 Mar 2010 21:03:17 +0100 (CET) Subject: [pypy-svn] r71868 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100306200317.AB98A5105A@codespeak.net> Author: dan Date: Sat Mar 6 21:02:19 2010 New Revision: 71868 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Added basic sdarray setitem testing, fixed an obvious error in implementation. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Sat Mar 6 21:02:19 2010 @@ -4,6 +4,8 @@ from pypy.interpreter.gateway import interp2app from pypy.rlib.debug import make_sure_not_resized +from pypy.objspace.std.sliceobject import W_SliceObject + from pypy.module.micronumpy.array import BaseNumArray from pypy.module.micronumpy.array import base_typedef from pypy.module.micronumpy.array import \ @@ -156,8 +158,9 @@ def descr_getitem(self, w_index): space = self.space if space.is_true(space.isinstance(w_index, space.w_slice)): + assert isinstance(w_index, W_SliceObject) start, stop, step, slen = w_index.indices4(space, self.len()) - res = sdresult(self.dtype.code)(space, slen, self.dtype) + res = NumArray(space, slen, self.dtype) if step == 1: res.storage[:] = self.storage[start:stop] else: @@ -170,7 +173,7 @@ index = space.int_w(w_index) except TypeError, e: raise OperationError(space.w_IndexError, - space.wrap('Wrong index')) + space.wrap("index must either be an int or a sequence")) try: return space.wrap(self.storage[index]) except IndexError: @@ -181,6 +184,7 @@ def descr_setitem(self, w_index, w_value): space = self.space if space.is_true(space.isinstance(w_index, space.w_slice)): + assert isinstance(w_index, W_SliceObject) start, stop, step, slen = w_index.indices4(space, self.len()) try: space.iter(w_value) @@ -196,8 +200,8 @@ for i in range(start, stop, step): self.storage[i] = value return - lop = space.int_w(space.len(w_value)) - if lop != slen: + operand_length = space.int_w(space.len(w_value)) + if operand_length != slen: raise OperationError(space.w_TypeError, space.wrap('shape mismatch')) value = space.fixedview(w_value) @@ -212,11 +216,16 @@ else: try: index = space.int_w(w_index) - except TypeError, e: - raise OperationError(space.w_IndexError, - space.wrap('Wrong index')) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError(space.w_ValueError, + space.wrap("can't understand index")) #FIXME: more meaningful message based on type try: self.storage[index] = coerce(space, w_value) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError(space.w_ValueError, + space.wrap("can't understand value")) #FIXME: more meaningful message based on type except IndexError: raise OperationError(space.w_IndexError, space.wrap("list index out of range")) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Sat Mar 6 21:02:19 2010 @@ -139,11 +139,13 @@ def test_setitem_getitem(self): from numpy import zeros + compare = self.compare + ar = zeros(8, dtype=int) assert ar[0] == 0 ar[1] = 3 assert ar[1] == 3 - raises((TypeError, ValueError), ar.__getitem__, 'xyz') + raises((TypeError, ValueError), ar.__getitem__, 'xyz') #FIXME: why TypeError? raises(IndexError, ar.__getitem__, 38) assert ar[-2] == 0 assert ar[-7] == 3 @@ -151,11 +153,17 @@ ar[2:3] = [5] assert ar[2] == 5 - compare = self.compare assert compare(ar[1:3], [3, 5]) assert compare(ar[-6:-4], [5, 0]) assert compare(ar[-6:-8:-1], [5, 3]) + #setitem + ar[3] = 2 + assert ar[3] == 2 + ar[5] = 3.5 + assert ar[5] == 3 + raises(ValueError, ar.__setitem__, 0, [99]) + raises(ValueError, ar.__setitem__, 0, 'f') def test_minimum(self): from numpy import zeros, minimum From arigo at codespeak.net Mon Mar 8 10:32:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 10:32:08 +0100 (CET) Subject: [pypy-svn] r71869 - in pypy/trunk/pypy/module/imp: . test Message-ID: <20100308093208.D0D4E51054@codespeak.net> Author: arigo Date: Mon Mar 8 10:32:07 2010 New Revision: 71869 Modified: pypy/trunk/pypy/module/imp/importing.py pypy/trunk/pypy/module/imp/test/test_import.py Log: Remove the special-casing of mtime=0, which was bogus anyway because the stream's position would not be advanced past the modification time stored in the .pyc. Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Mon Mar 8 10:32:07 2010 @@ -647,9 +647,9 @@ d = x & 0xff stream.write(chr(a) + chr(b) + chr(c) + chr(d)) -def check_compiled_module(space, pycfilename, expected_mtime=0): +def check_compiled_module(space, pycfilename, expected_mtime): """ - Check if a pyc file's magic number and (optionally) mtime match. + Check if a pyc file's magic number and mtime match. """ stream = None try: @@ -658,11 +658,10 @@ if magic != get_pyc_magic(space): stream.close() return None - if expected_mtime != 0: - pyc_mtime = _r_long(stream) - if pyc_mtime != expected_mtime: - stream.close() - return None + pyc_mtime = _r_long(stream) + if pyc_mtime != expected_mtime: + stream.close() + return None return stream except StreamErrors: if stream: Modified: pypy/trunk/pypy/module/imp/test/test_import.py ============================================================================== --- pypy/trunk/pypy/module/imp/test/test_import.py (original) +++ pypy/trunk/pypy/module/imp/test/test_import.py Mon Mar 8 10:32:07 2010 @@ -496,6 +496,12 @@ cpathname, mtime+1) assert ret is None + + # also check with expected mtime==0 (nothing special any more about 0) + ret = importing.check_compiled_module(space, + cpathname, + 0) + assert ret is None os.remove(cpathname) # check for wrong version From arigo at codespeak.net Mon Mar 8 10:32:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 10:32:31 +0100 (CET) Subject: [pypy-svn] r71870 - in pypy/trunk/pypy/translator/sandbox: . test Message-ID: <20100308093231.68AE451054@codespeak.net> Author: arigo Date: Mon Mar 8 10:32:29 2010 New Revision: 71870 Modified: pypy/trunk/pypy/translator/sandbox/pypy_interact.py pypy/trunk/pypy/translator/sandbox/test/test_pypy_interact.py pypy/trunk/pypy/translator/sandbox/test/test_vfs.py pypy/trunk/pypy/translator/sandbox/vfs.py Log: In sandboxing mode, don't deliver .pyc files. The .py files only are enough, and the .pyc files were not considered anyway because the .py files had a mtime of 0. (Which caused troubles because of the bug fixed in r71869.) Modified: pypy/trunk/pypy/translator/sandbox/pypy_interact.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/pypy_interact.py (original) +++ pypy/trunk/pypy/translator/sandbox/pypy_interact.py Mon Mar 8 10:32:29 2010 @@ -45,18 +45,21 @@ # * can access its own executable # * can access the pure Python libraries # * can access the temporary usession directory as /tmp + exclude = ['.pyc', '.pyo'] if self.tmpdir is None: tmpdirnode = Dir({}) else: - tmpdirnode = RealDir(self.tmpdir) + tmpdirnode = RealDir(self.tmpdir, exclude=exclude) pypydist = os.path.dirname(os.path.abspath(autopath.pypydir)) return Dir({ 'bin': Dir({ 'pypy-c': RealFile(self.executable), - 'lib-python': RealDir(os.path.join(pypydist, 'lib-python')), + 'lib-python': RealDir(os.path.join(pypydist, 'lib-python'), + exclude=exclude), 'pypy': Dir({ - 'lib': RealDir(os.path.join(pypydist, 'pypy', 'lib')), + 'lib': RealDir(os.path.join(pypydist, 'pypy', 'lib'), + exclude=exclude), }), }), 'tmp': tmpdirnode, 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 Mon Mar 8 10:32:29 2010 @@ -36,6 +36,12 @@ assert_(False, "os.stat('site') should have failed") 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") + try: + os.stat('/bin/lib-python/modified-2.5.2/site.pyc') + except OSError: + pass + else: + assert_(False, "os.stat('....pyc') should have failed") fd = os.open('/bin/lib-python/modified-2.5.2/site.py', os.O_RDONLY, 0666) length = 8192 ofs = 0 Modified: pypy/trunk/pypy/translator/sandbox/test/test_vfs.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/test/test_vfs.py (original) +++ pypy/trunk/pypy/translator/sandbox/test/test_vfs.py Mon Mar 8 10:32:29 2010 @@ -90,3 +90,19 @@ else: py.test.raises(OSError, v_test_vfs.join, '.hidden') py.test.raises(OSError, v_test_vfs.join, '.subdir2') + +def test_realdir_exclude(): + xdir = udir.ensure('test_realdir_exclude', dir=1) + xdir.ensure('test_realdir_exclude.yes') + xdir.ensure('test_realdir_exclude.no') + v_udir = RealDir(str(udir), exclude=['.no']) + v_xdir = v_udir.join('test_realdir_exclude') + assert 'test_realdir_exclude.yes' in v_xdir.keys() + assert 'test_realdir_exclude.no' not in v_xdir.keys() + v_xdir.join('test_realdir_exclude.yes') # works + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.no') + # Windows and Mac tests, for the case + py.test.raises(OSError, v_xdir.join, 'Test_RealDir_Exclude.no') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.No') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.nO') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.NO') Modified: pypy/trunk/pypy/translator/sandbox/vfs.py ============================================================================== --- pypy/trunk/pypy/translator/sandbox/vfs.py (original) +++ pypy/trunk/pypy/translator/sandbox/vfs.py Mon Mar 8 10:32:29 2010 @@ -64,21 +64,30 @@ # with '.' simply don't exist. If follow_links=True, then symlinks are # transparently followed (they look like a regular file or directory to # the sandboxed process). If follow_links=False, the subprocess is - # not allowed to access them at all. - def __init__(self, path, show_dotfiles=False, follow_links=False): + # not allowed to access them at all. Finally, exclude is a list of + # file endings that we filter out (note that we also filter out files + # with the same ending but a different case, to be safe). + def __init__(self, path, show_dotfiles=False, follow_links=False, + exclude=[]): self.path = path self.show_dotfiles = show_dotfiles self.follow_links = follow_links + self.exclude = [excl.lower() for excl in exclude] def __repr__(self): return '' % (self.path,) def keys(self): names = os.listdir(self.path) if not self.show_dotfiles: names = [name for name in names if not name.startswith('.')] + for excl in self.exclude: + names = [name for name in names if not name.lower().endswith(excl)] return names def join(self, name): if name.startswith('.') and not self.show_dotfiles: raise OSError(errno.ENOENT, name) + for excl in self.exclude: + if name.lower().endswith(excl): + raise OSError(errno.ENOENT, name) path = os.path.join(self.path, name) if self.follow_links: st = os.stat(path) @@ -86,7 +95,8 @@ st = os.lstat(path) if stat.S_ISDIR(st.st_mode): return RealDir(path, show_dotfiles = self.show_dotfiles, - follow_links = self.follow_links) + follow_links = self.follow_links, + exclude = self.exclude) elif stat.S_ISREG(st.st_mode): return RealFile(path) else: From arigo at codespeak.net Mon Mar 8 10:57:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 10:57:11 +0100 (CET) Subject: [pypy-svn] r71871 - pypy/trunk/pypy/translator/goal Message-ID: <20100308095711.1C0F251054@codespeak.net> Author: arigo Date: Mon Mar 8 10:57:09 2010 New Revision: 71871 Modified: pypy/trunk/pypy/translator/goal/targetpypystandalone.py Log: Following cfbolz's suggestion, disable pyc files handling altogether in pypy-c-sandbox translations. Modified: pypy/trunk/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/trunk/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/trunk/pypy/translator/goal/targetpypystandalone.py Mon Mar 8 10:57:09 2010 @@ -186,6 +186,10 @@ #elif config.objspace.usemodules.clr: # config.translation.backend == "cli" + if config.translation.sandbox: + config.objspace.lonepycfiles = False + config.objspace.usepycfiles = False + config.objspace.nofaking = True config.objspace.compiler = "ast" config.translating = True From arigo at codespeak.net Mon Mar 8 10:58:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 10:58:40 +0100 (CET) Subject: [pypy-svn] r71872 - pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache Message-ID: <20100308095840.C8DC351054@codespeak.net> Author: arigo Date: Mon Mar 8 10:58:39 2010 New Revision: 71872 Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py Log: Fix when running "python rebuild.py". Modified: pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py ============================================================================== --- pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py (original) +++ pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/rebuild.py Mon Mar 8 10:58:39 2010 @@ -5,7 +5,7 @@ import os, sys import py -_dirpath = os.path.dirname(__file__) +_dirpath = os.path.dirname(__file__) or os.curdir from pypy.tool.ansi_print import ansi_log log = py.log.Producer("ctypes_config_cache") From arigo at codespeak.net Mon Mar 8 11:03:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 11:03:08 +0100 (CET) Subject: [pypy-svn] r71873 - in pypy/trunk: ctypes_configure ctypes_configure/test pypy/lib pypy/lib/app_test pypy/lib/ctypes_config_cache pypy/lib/ctypes_config_cache/test pypy/translator/goal Message-ID: <20100308100308.909A551054@codespeak.net> Author: arigo Date: Mon Mar 8 11:03:06 2010 New Revision: 71873 Added: pypy/trunk/ctypes_configure/dumpcache.py - copied unchanged from r71872, pypy/branch/ctypes-configure-cache-2/ctypes_configure/dumpcache.py pypy/trunk/ctypes_configure/test/test_dumpcache.py - copied unchanged from r71872, pypy/branch/ctypes-configure-cache-2/ctypes_configure/test/test_dumpcache.py pypy/trunk/pypy/lib/app_test/test_syslog.py - copied unchanged from r71872, pypy/branch/ctypes-configure-cache-2/pypy/lib/app_test/test_syslog.py pypy/trunk/pypy/lib/ctypes_config_cache/ (props changed) - copied from r71872, pypy/branch/ctypes-configure-cache-2/pypy/lib/ctypes_config_cache/ Removed: pypy/trunk/pypy/lib/ctypes_configure Modified: pypy/trunk/ctypes_configure/cbuild.py pypy/trunk/ctypes_configure/configure.py pypy/trunk/pypy/lib/_hashlib.py pypy/trunk/pypy/lib/_locale.py pypy/trunk/pypy/lib/app_test/test_hashlib.py pypy/trunk/pypy/lib/app_test/test_locale.py pypy/trunk/pypy/lib/app_test/test_pyexpat.py pypy/trunk/pypy/lib/app_test/test_resource.py pypy/trunk/pypy/lib/ctypes_config_cache/test/ (props changed) pypy/trunk/pypy/lib/pyexpat.py pypy/trunk/pypy/lib/resource.py pypy/trunk/pypy/lib/syslog.py pypy/trunk/pypy/translator/goal/targetpypystandalone.py Log: Merge branch/ctypes-configure-cache-2. Remove the app-level usage of ctypes_configure, and replace it with precomputing and caching the dependency information. It should remove the need for a C compiler to exist at pypy-c run-time. Modified: pypy/trunk/ctypes_configure/cbuild.py ============================================================================== --- pypy/trunk/ctypes_configure/cbuild.py (original) +++ pypy/trunk/ctypes_configure/cbuild.py Mon Mar 8 11:03:06 2010 @@ -5,7 +5,7 @@ debug = 0 -configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') +configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure-') class ExternalCompilationInfo(object): Modified: pypy/trunk/ctypes_configure/configure.py ============================================================================== --- pypy/trunk/ctypes_configure/configure.py (original) +++ pypy/trunk/ctypes_configure/configure.py Mon Mar 8 11:03:06 2010 @@ -164,7 +164,7 @@ for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigEntry): - entries.append((key, value)) + entries.append((key, value)) if entries: # can be empty if there are only CConfigSingleEntries writer = _CWriter(CConfig) @@ -201,7 +201,6 @@ writer = _CWriter(CConfig) writer.write_header() res[key] = value.question(writer.ask_gcc) - return res # ____________________________________________________________ @@ -210,7 +209,6 @@ class CConfigEntry(object): "Abstract base class." - class Struct(CConfigEntry): """An entry in a CConfig class that stands for an externally defined structure. @@ -313,7 +311,6 @@ S.__name__ = name return S - class SimpleType(CConfigEntry): """An entry in a CConfig class that stands for an externally defined simple numeric type. @@ -350,7 +347,6 @@ ctype = fixup_ctype(ctype, self.name, (size, sign)) return ctype - class ConstantInteger(CConfigEntry): """An entry in a CConfig class that stands for an externally defined integer constant. Modified: pypy/trunk/pypy/lib/_hashlib.py ============================================================================== --- pypy/trunk/pypy/lib/_hashlib.py (original) +++ pypy/trunk/pypy/lib/_hashlib.py Mon Mar 8 11:03:06 2010 @@ -1,6 +1,8 @@ from ctypes import * import ctypes.util -from ctypes_configure import configure + +# load the platform-specific cache made by running hashlib.ctc.py +from ctypes_config_cache._hashlib_cache import * # Note: OpenSSL on OS X only provides md5 and sha1 libpath = ctypes.util.find_library('ssl') @@ -16,18 +18,6 @@ else: return buffer(x)[:] -class CConfig: - _compilation_info_ = configure.ExternalCompilationInfo( - includes=['openssl/evp.h'], - ) - EVP_MD = configure.Struct('EVP_MD', - []) - EVP_MD_CTX = configure.Struct('EVP_MD_CTX', - [('digest', c_void_p)]) -c = configure.configure(CConfig) -EVP_MD_CTX = c['EVP_MD_CTX'] -EVP_MD = c['EVP_MD'] - def patch_fields(fields): res = [] for k, v in fields: @@ -39,7 +29,6 @@ class EVP_MD_CTX(Structure): _fields_ = patch_fields(EVP_MD_CTX._fields_) -del c # OpenSSL initialization lib.OpenSSL_add_all_digests() Modified: pypy/trunk/pypy/lib/_locale.py ============================================================================== --- pypy/trunk/pypy/lib/_locale.py (original) +++ pypy/trunk/pypy/lib/_locale.py Mon Mar 8 11:03:06 2010 @@ -7,48 +7,16 @@ c_ubyte, c_int, c_char_p, c_wchar_p) from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno -from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + +# load the platform-specific cache made by running locale.ctc.py +from ctypes_config_cache._locale_cache import * + size_t = c_int # XXX check where this comes from CHAR_MAX = 127 -_CONSTANTS = ( - 'LC_CTYPE', - 'LC_NUMERIC', - 'LC_TIME', - 'LC_COLLATE', - 'LC_MONETARY', - 'LC_MESSAGES', - 'LC_ALL', - 'LC_PAPER', - 'LC_NAME', - 'LC_ADDRESS', - 'LC_TELEPHONE', - 'LC_MEASUREMENT', - 'LC_IDENTIFICATION', -) - -class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) -for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) - -try: - locale_config = configure(LocaleConfigure, noerr=True) -except Exception, e: - # should probably be moved into configure() - # as an optional feature - raise ImportError("%s: %s" % (e.__class__, e)) - -for key in _CONSTANTS: - globals()[key] = locale_config[key] -del LocaleConfigure -del locale_config - -HAS_LANGINFO = True # Ubuntu Gusty i386 structure class lconv(Structure): @@ -288,29 +256,6 @@ raise NotImplementedError() if HAS_LANGINFO: - # this is incomplete list - langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' - 'YESEXPR NOEXPR CRNCYSTR').split(" ") - for i in range(1, 8): - langinfo_names.append("DAY_%d" % i) - langinfo_names.append("ABDAY_%d" % i) - for i in range(1, 13): - langinfo_names.append("MON_%d" % i) - langinfo_names.append("ABMON_%d" % i) - - class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) - nl_item = SimpleType('nl_item') - for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) - - config = configure(LanginfoConfigure) - nl_item = config['nl_item'] - for key in langinfo_names: - globals()[key] = config[key] - del LanginfoConfigure - del config - _nl_langinfo = libc.nl_langinfo _nl_langinfo.argtypes = (nl_item,) _nl_langinfo.restype = c_char_p @@ -369,9 +314,8 @@ 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', 'bindtextdomain', 'CHAR_MAX', -) + _CONSTANTS + tuple(langinfo_names) +) + ALL_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: __all__ += ('nl_langinfo',) - Modified: pypy/trunk/pypy/lib/app_test/test_hashlib.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_hashlib.py (original) +++ pypy/trunk/pypy/lib/app_test/test_hashlib.py Mon Mar 8 11:03:06 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('hashlib.ctc.py') + from pypy.lib import hashlib, _hashlib def test_unicode(): Modified: pypy/trunk/pypy/lib/app_test/test_locale.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_locale.py (original) +++ pypy/trunk/pypy/lib/app_test/test_locale.py Mon Mar 8 11:03:06 2010 @@ -1,14 +1,19 @@ import py -import locale import sys +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('locale.ctc.py') + +from pypy.lib import _locale + + def setup_module(mod): if sys.platform == 'darwin': py.test.skip("Locale support on MacOSX is minimal and cannot be tested") class TestLocale: def setup_class(cls): - cls.oldlocale = locale.setlocale(locale.LC_NUMERIC) + cls.oldlocale = _locale.setlocale(_locale.LC_NUMERIC) if sys.platform.startswith("win"): cls.tloc = "en" elif sys.platform.startswith("freebsd"): @@ -16,14 +21,15 @@ else: cls.tloc = "en_US.UTF8" try: - locale.setlocale(locale.LC_NUMERIC, cls.tloc) - except locale.Error: + _locale.setlocale(_locale.LC_NUMERIC, cls.tloc) + except _locale.Error: py.test.skip("test locale %s not supported" % cls.tloc) def teardown_class(cls): - locale.setlocale(locale.LC_NUMERIC, cls.oldlocale) + _locale.setlocale(_locale.LC_NUMERIC, cls.oldlocale) def test_format(self): + py.test.skip("XXX fix or kill me") def testformat(formatstr, value, grouping = 0, output=None): if output: @@ -41,8 +47,11 @@ testformat("%20.f", -42, grouping=1, output=' -42') testformat("%+10.f", -4200, grouping=1, output=' -4,200') testformat("%-10.f", 4200, grouping=1, output='4,200 ') - # Invoke getpreferredencoding to make sure it does not cause exceptions, - locale.getpreferredencoding() + + def test_getpreferredencoding(self): + py.test.skip("XXX fix or kill me") + # Invoke getpreferredencoding to make sure it does not cause exceptions + _locale.getpreferredencoding() # Test BSD Rune locale's bug for isctype functions. def test_bsd_bug(self): @@ -51,8 +60,8 @@ result = getattr(s, method)() assert result == output - oldlocale = locale.setlocale(locale.LC_CTYPE) - locale.setlocale(locale.LC_CTYPE, self.tloc) + oldlocale = _locale.setlocale(_locale.LC_CTYPE) + _locale.setlocale(_locale.LC_CTYPE, self.tloc) try: teststrop('\x20', 'isspace', True) teststrop('\xa0', 'isspace', False) @@ -66,4 +75,4 @@ teststrop('\xcc\x85', 'lower', '\xcc\x85') teststrop('\xed\x95\xa0', 'upper', '\xed\x95\xa0') finally: - locale.setlocale(locale.LC_CTYPE, oldlocale) + _locale.setlocale(_locale.LC_CTYPE, oldlocale) Modified: pypy/trunk/pypy/lib/app_test/test_pyexpat.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_pyexpat.py (original) +++ pypy/trunk/pypy/lib/app_test/test_pyexpat.py Mon Mar 8 11:03:06 2010 @@ -4,6 +4,9 @@ import StringIO, sys import unittest, py +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('pyexpat.ctc.py') + from pypy.lib import pyexpat #from xml.parsers import expat expat = pyexpat Modified: pypy/trunk/pypy/lib/app_test/test_resource.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_resource.py (original) +++ pypy/trunk/pypy/lib/app_test/test_resource.py Mon Mar 8 11:03:06 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('resource.ctc.py') + from pypy.lib import resource def test_resource(): Modified: pypy/trunk/pypy/lib/pyexpat.py ============================================================================== --- pypy/trunk/pypy/lib/pyexpat.py (original) +++ pypy/trunk/pypy/lib/pyexpat.py Mon Mar 8 11:03:06 2010 @@ -1,46 +1,15 @@ import ctypes import ctypes.util -from ctypes_configure import configure from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p import sys +# load the platform-specific cache made by running pyexpat.ctc.py +from ctypes_config_cache._pyexpat_cache import * + + lib = ctypes.CDLL(ctypes.util.find_library('expat')) -class CConfigure: - _compilation_info_ = configure.ExternalCompilationInfo( - includes = ['expat.h'], - libraries = ['expat'], - pre_include_lines = [ - '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], - ) - - XML_Char = configure.SimpleType('XML_Char', ctypes.c_char) - XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') - for name in ['XML_PARAM_ENTITY_PARSING_NEVER', - 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', - 'XML_PARAM_ENTITY_PARSING_ALWAYS']: - locals()[name] = configure.ConstantInteger(name) - - XML_Encoding = configure.Struct('XML_Encoding',[ - ('data', c_void_p), - ('convert', c_void_p), - ('release', c_void_p), - ('map', c_int * 256)]) - XML_Content = configure.Struct('XML_Content',[ - ('numchildren', c_int), - ('children', c_void_p), - ('name', c_char_p), - ('type', c_int), - ('quant', c_int), - ]) - # this is insanely stupid - XML_FALSE = configure.ConstantInteger('XML_FALSE') - XML_TRUE = configure.ConstantInteger('XML_TRUE') - -info = configure.configure(CConfigure) -for k, v in info.items(): - globals()[k] = v XML_Content.children = POINTER(XML_Content) XML_Parser = ctypes.c_void_p # an opaque pointer Modified: pypy/trunk/pypy/lib/resource.py ============================================================================== --- pypy/trunk/pypy/lib/resource.py (original) +++ pypy/trunk/pypy/lib/resource.py Mon Mar 8 11:03:06 2010 @@ -2,45 +2,18 @@ if sys.platform == 'win32': raise ImportError('resource module not available for win32') +# load the platform-specific cache made by running resource.ctc.py +from ctypes_config_cache._resource_cache import * + from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno from ctypes import Structure, c_int, c_long, byref, sizeof from errno import EINVAL, EPERM -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, - SimpleType) import _structseq class error(Exception): pass -_CONSTANTS = ( - 'RLIM_INFINITY', - 'RLIM_NLIMITS', -) -_OPTIONAL_CONSTANTS = ( - 'RLIMIT_CPU', - 'RLIMIT_FSIZE', - 'RLIMIT_DATA', - 'RLIMIT_STACK', - 'RLIMIT_CORE', - 'RLIMIT_RSS', - 'RLIMIT_NPROC', - 'RLIMIT_NOFILE', - 'RLIMIT_OFILE', - 'RLIMIT_MEMLOCK', - 'RLIMIT_AS', - 'RLIMIT_LOCKS', - 'RLIMIT_SIGPENDING', - 'RLIMIT_MSGQUEUE', - 'RLIMIT_NICE', - 'RLIMIT_RTPRIO', - 'RLIMIT_VMEM', - - 'RUSAGE_BOTH', - 'RUSAGE_SELF', - 'RUSAGE_CHILDREN', -) # Read required libc functions _getrusage = libc.getrusage @@ -52,27 +25,6 @@ from os import sysconf _getpagesize = None -# Setup our configure -class ResourceConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) - rlim_t = SimpleType('rlim_t') -for key in _CONSTANTS: - setattr(ResourceConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(ResourceConfigure, key, DefinedConstantInteger(key)) - -# Configure constants and types -config = configure(ResourceConfigure) -rlim_t = config['rlim_t'] -sizeof_rlim_t = 1<<(sizeof(rlim_t) * 8) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -del config class timeval(Structure): _fields_ = ( @@ -126,9 +78,9 @@ ru_nivcsw = _structseq.structseqfield(15) def rlimit_check_bounds(rlim_cur, rlim_max): - if rlim_cur > sizeof_rlim_t: + if rlim_cur > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_cur) - if rlim_max > sizeof_rlim_t: + if rlim_max > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_max) class rlimit(Structure): @@ -202,10 +154,9 @@ # Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE return sysconf("SC_PAGESIZE") -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'error', 'timeval', 'struct_rusage', 'rlimit', 'getrusage', 'getrlimit', 'setrlimit', 'getpagesize', ) -del optional_constants - +del ALL_CONSTANTS Modified: pypy/trunk/pypy/lib/syslog.py ============================================================================== --- pypy/trunk/pypy/lib/syslog.py (original) +++ pypy/trunk/pypy/lib/syslog.py Mon Mar 8 11:03:06 2010 @@ -9,79 +9,11 @@ if sys.platform == 'win32': raise ImportError("No syslog on Windows") +# load the platform-specific cache made by running syslog.ctc.py +from ctypes_config_cache._syslog_cache import * + from ctypes_support import standard_c_lib as libc from ctypes import c_int, c_char_p -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) - -_CONSTANTS = ( - 'LOG_EMERG', - 'LOG_ALERT', - 'LOG_CRIT', - 'LOG_ERR', - 'LOG_WARNING', - 'LOG_NOTICE', - 'LOG_INFO', - 'LOG_DEBUG', - - 'LOG_PID', - 'LOG_CONS', - 'LOG_NDELAY', - - 'LOG_KERN', - 'LOG_USER', - 'LOG_MAIL', - 'LOG_DAEMON', - 'LOG_AUTH', - 'LOG_LPR', - 'LOG_LOCAL0', - 'LOG_LOCAL1', - 'LOG_LOCAL2', - 'LOG_LOCAL3', - 'LOG_LOCAL4', - 'LOG_LOCAL5', - 'LOG_LOCAL6', - 'LOG_LOCAL7', -) -_OPTIONAL_CONSTANTS = ( - 'LOG_NOWAIT', - 'LOG_PERROR', - - 'LOG_SYSLOG', - 'LOG_CRON', - 'LOG_UUCP', - 'LOG_NEWS', -) - -# Constant aliases if there are not defined -_ALIAS = ( - ('LOG_SYSLOG', 'LOG_DAEMON'), - ('LOG_CRON', 'LOG_DAEMON'), - ('LOG_NEWS', 'LOG_MAIL'), - ('LOG_UUCP', 'LOG_MAIL'), -) - -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) - -config = configure(SyslogConfigure) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -for alias, key in _ALIAS: - if alias in optional_constants: - continue - globals()[alias] = globals()[key] - optional_constants.append(alias) -del config # Real prototype is: # void syslog(int priority, const char *format, ...); @@ -124,9 +56,8 @@ def LOG_UPTO(pri): return (1 << (pri + 1)) - 1 -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'openlog', 'syslog', 'closelog', 'setlogmask', 'LOG_MASK', 'LOG_UPTO') -del optional_constants - +del ALL_CONSTANTS Modified: pypy/trunk/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/trunk/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/trunk/pypy/translator/goal/targetpypystandalone.py Mon Mar 8 11:03:06 2010 @@ -220,6 +220,9 @@ return PyPyJitPolicy() def get_entry_point(self, config): + from pypy.lib.ctypes_config_cache import rebuild + rebuild.try_rebuild() + space = make_objspace(config) # manually imports app_main.py From antocuni at codespeak.net Mon Mar 8 12:01:31 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 8 Mar 2010 12:01:31 +0100 (CET) Subject: [pypy-svn] r71874 - pypy/extradoc/talk/pycon-italy-2010 Message-ID: <20100308110131.4BC9051056@codespeak.net> Author: antocuni Date: Mon Mar 8 12:01:30 2010 New Revision: 71874 Added: pypy/extradoc/talk/pycon-italy-2010/ pypy/extradoc/talk/pycon-italy-2010/abstract.txt (contents, props changed) Log: abstract for my talk at pycon italy Added: pypy/extradoc/talk/pycon-italy-2010/abstract.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon-italy-2010/abstract.txt Mon Mar 8 12:01:30 2010 @@ -0,0 +1,14 @@ +PyPy 1.2: snakes never crawled so fast +====================================== + +PyPy 1.2 has been recently released: the highlight of the new version is on +the new JIT compiler, which can hugely increase the performances of Python +programs. + +In this talk we explain how the JIT compiler is implemented, and most +importantly how it works from the point of view of the user: in particular, we +see which kind of programs can benefit most from the presence of the JIT. + +Finally, we present a way to integrate PyPy into existing applications based +on CPython, to gradually make the performance critical parts to be executed by +PyPy and get its benefits already now. From antocuni at codespeak.net Mon Mar 8 12:16:10 2010 From: antocuni at codespeak.net (antocuni at codespeak.net) Date: Mon, 8 Mar 2010 12:16:10 +0100 (CET) Subject: [pypy-svn] r71875 - pypy/extradoc/talk/pycon-italy-2010 Message-ID: <20100308111610.6AE5A5105A@codespeak.net> Author: antocuni Date: Mon Mar 8 12:16:09 2010 New Revision: 71875 Modified: pypy/extradoc/talk/pycon-italy-2010/abstract.txt Log: add the italian translation Modified: pypy/extradoc/talk/pycon-italy-2010/abstract.txt ============================================================================== --- pypy/extradoc/talk/pycon-italy-2010/abstract.txt (original) +++ pypy/extradoc/talk/pycon-italy-2010/abstract.txt Mon Mar 8 12:16:09 2010 @@ -12,3 +12,22 @@ Finally, we present a way to integrate PyPy into existing applications based on CPython, to gradually make the performance critical parts to be executed by PyPy and get its benefits already now. + + + +Italian translation +------------------- + +PyPy 1.2 ? stato da poco rilasciato: la caratteristica saliente dalla nuova +versione ? il nuovo compilatore JIT, che pu? incrementare notevolmente le +prestazione dei programmi in Python. + +In questo talk, spiegheremo come il compilatore JIT ? implementato e, aspetto +pi? importante, come funziona dal punto di vista dell'utente: in particolare, +vedremo quali tipi di programma possono trarre i maggiori benefici dalla +presenza del JIT. + +Infine, presenteremo un modo per integrare PyPy all'interno applicazioni gi? +esistenti basate su CPython, per far s? che gradualmente le parti pi? critiche +per le prestazioni siano eseguite da PyPy, in modo da poter godere dei suoi +benefici fin da subito. From arigo at codespeak.net Mon Mar 8 12:38:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 12:38:11 +0100 (CET) Subject: [pypy-svn] r71876 - pypy/branch/jit-constptr Message-ID: <20100308113811.2099B51054@codespeak.net> Author: arigo Date: Mon Mar 8 12:38:09 2010 New Revision: 71876 Added: pypy/branch/jit-constptr/ - copied from r71875, pypy/trunk/ Log: A branch in which to support the x86 backend using directly ConstPtrs. Requires a bit of support from the GC to be able to fix the addresses written in the assembler when the objects move. From arigo at codespeak.net Mon Mar 8 14:07:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 14:07:34 +0100 (CET) Subject: [pypy-svn] r71877 - pypy/branch/ctypes-configure-cache-2 Message-ID: <20100308130734.3BB7351054@codespeak.net> Author: arigo Date: Mon Mar 8 14:07:33 2010 New Revision: 71877 Removed: pypy/branch/ctypes-configure-cache-2/ Log: Remove merged branch. From arigo at codespeak.net Mon Mar 8 14:07:48 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 14:07:48 +0100 (CET) Subject: [pypy-svn] r71878 - pypy/branch/ctypes-configure-cache Message-ID: <20100308130748.EC39E51054@codespeak.net> Author: arigo Date: Mon Mar 8 14:07:47 2010 New Revision: 71878 Removed: pypy/branch/ctypes-configure-cache/ Log: Remove branch merged in the branch that was merged in trunk From arigo at codespeak.net Mon Mar 8 16:22:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 16:22:16 +0100 (CET) Subject: [pypy-svn] r71885 - in pypy/branch/jit-constptr/pypy: jit/backend/llsupport jit/backend/llsupport/test jit/backend/x86 jit/backend/x86/test rpython/memory/gc rpython/memory/gctransform Message-ID: <20100308152216.7354951054@codespeak.net> Author: arigo Date: Mon Mar 8 16:22:14 2010 New Revision: 71885 Added: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py - copied, changed from r71876, pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py pypy/branch/jit-constptr/pypy/jit/backend/x86/runner.py pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py pypy/branch/jit-constptr/pypy/rpython/memory/gc/base.py pypy/branch/jit-constptr/pypy/rpython/memory/gctransform/framework.py Log: In-progress. Adds a hook in the GC, called before and after tracing of some kinds of objects (more precisely, the arrays with GcRefs in the varsized part, and which are not just GcArrays). Start using the hook from the JIT. See test_GcRefHandler. The goal is to correct the addresses of objects, or of individual fields inside these objects, that are hard-coded in assembler. Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py Mon Mar 8 16:22:14 2010 @@ -1,20 +1,8 @@ -from pypy.rlib import rgc -from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.debug import fatalerror -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.annlowlevel import llhelper -from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, ConstPtr -from pypy.jit.metainterp.history import AbstractDescr -from pypy.jit.metainterp.resoperation import ResOperation, rop +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr from pypy.jit.backend.llsupport import symbolic from pypy.jit.backend.llsupport.symbolic import WORD from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr -from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr -from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr -from pypy.jit.backend.llsupport.descr import get_call_descr -from pypy.rlib.rarithmetic import r_ulonglong, r_uint +from pypy.jit.backend.llsupport.descr import GcCache # ____________________________________________________________ @@ -121,480 +109,11 @@ get_funcptr_for_newstr = None get_funcptr_for_newunicode = None - # ____________________________________________________________ -# All code below is for the hybrid GC - - -class GcRefList: - """Handles all references from the generated assembler to GC objects. - This is implemented as a nonmovable, but GC, list; the assembler contains - code that will (for now) always read from this list.""" - - GCREF_LIST = lltype.GcArray(llmemory.GCREF) # followed by the GC - - HASHTABLE = rffi.CArray(llmemory.Address) # ignored by the GC - HASHTABLE_BITS = 10 - HASHTABLE_SIZE = 1 << HASHTABLE_BITS - - def initialize(self): - if we_are_translated(): n = 2000 - else: n = 10 # tests only - self.list = self.alloc_gcref_list(n) - self.nextindex = 0 - self.oldlists = [] - # A pseudo dictionary: it is fixed size, and it may contain - # random nonsense after a collection moved the objects. It is only - # used to avoid too many duplications in the GCREF_LISTs. - self.hashtable = lltype.malloc(self.HASHTABLE, - self.HASHTABLE_SIZE+1, - flavor='raw') - dummy = lltype.direct_ptradd(lltype.direct_arrayitems(self.hashtable), - self.HASHTABLE_SIZE) - dummy = llmemory.cast_ptr_to_adr(dummy) - for i in range(self.HASHTABLE_SIZE+1): - self.hashtable[i] = dummy - - def alloc_gcref_list(self, n): - # Important: the GRREF_LISTs allocated are *non-movable*. This - # requires support in the gc (only the hybrid GC supports it so far). - if we_are_translated(): - list = rgc.malloc_nonmovable(self.GCREF_LIST, n) - assert list, "malloc_nonmovable failed!" - else: - list = lltype.malloc(self.GCREF_LIST, n) # for tests only - return list - - def get_address_of_gcref(self, gcref): - assert lltype.typeOf(gcref) == llmemory.GCREF - # first look in the hashtable, using an inexact hash (fails after - # the object moves) - addr = llmemory.cast_ptr_to_adr(gcref) - hash = llmemory.cast_adr_to_int(addr) - hash -= hash >> self.HASHTABLE_BITS - hash &= self.HASHTABLE_SIZE - 1 - addr_ref = self.hashtable[hash] - # the following test is safe anyway, because the addresses found - # in the hashtable are always the addresses of nonmovable stuff - # ('addr_ref' is an address inside self.list, not directly the - # address of a real moving GC object -- that's 'addr_ref.address[0]'.) - if addr_ref.address[0] == addr: - return addr_ref - # if it fails, add an entry to the list - if self.nextindex == len(self.list): - # reallocate first, increasing a bit the size every time - self.oldlists.append(self.list) - self.list = self.alloc_gcref_list(len(self.list) // 4 * 5) - self.nextindex = 0 - # add it - index = self.nextindex - self.list[index] = gcref - addr_ref = lltype.direct_ptradd(lltype.direct_arrayitems(self.list), - index) - addr_ref = llmemory.cast_ptr_to_adr(addr_ref) - self.nextindex = index + 1 - # record it in the hashtable - self.hashtable[hash] = addr_ref - return addr_ref - - -class GcRootMap_asmgcc: - """Handles locating the stack roots in the assembler. - This is the class supporting --gcrootfinder=asmgcc. - """ - LOC_REG = 0 - LOC_ESP_PLUS = 1 - LOC_EBP_PLUS = 2 - LOC_EBP_MINUS = 3 - - GCMAP_ARRAY = rffi.CArray(llmemory.Address) - CALLSHAPE_ARRAY = rffi.CArray(rffi.UCHAR) - - def __init__(self): - self._gcmap = lltype.nullptr(self.GCMAP_ARRAY) - self._gcmap_curlength = 0 - self._gcmap_maxlength = 0 - - def initialize(self): - # hack hack hack. Remove these lines and see MissingRTypeAttribute - # when the rtyper tries to annotate these methods only when GC-ing... - self.gcmapstart() - self.gcmapend() - - def gcmapstart(self): - return llmemory.cast_ptr_to_adr(self._gcmap) - - def gcmapend(self): - addr = self.gcmapstart() - if self._gcmap_curlength: - addr += llmemory.sizeof(llmemory.Address)*self._gcmap_curlength - return addr - - def put(self, retaddr, callshapeaddr): - """'retaddr' is the address just after the CALL. - 'callshapeaddr' is the address returned by encode_callshape().""" - index = self._gcmap_curlength - if index + 2 > self._gcmap_maxlength: - self._enlarge_gcmap() - self._gcmap[index] = retaddr - self._gcmap[index+1] = callshapeaddr - self._gcmap_curlength = index + 2 - - def _enlarge_gcmap(self): - newlength = 250 + self._gcmap_maxlength * 2 - newgcmap = lltype.malloc(self.GCMAP_ARRAY, newlength, flavor='raw') - oldgcmap = self._gcmap - for i in range(self._gcmap_curlength): - newgcmap[i] = oldgcmap[i] - self._gcmap = newgcmap - self._gcmap_maxlength = newlength - if oldgcmap: - lltype.free(oldgcmap, flavor='raw') - - def get_basic_shape(self): - return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 4(%ebp) - chr(self.LOC_EBP_MINUS | 4), # saved %ebx: at -4(%ebp) - chr(self.LOC_EBP_MINUS | 8), # saved %esi: at -8(%ebp) - chr(self.LOC_EBP_MINUS | 12), # saved %edi: at -12(%ebp) - chr(self.LOC_EBP_PLUS | 0), # saved %ebp: at (%ebp) - chr(0)] - - def _encode_num(self, shape, number): - assert number >= 0 - flag = 0 - while number >= 0x80: - shape.append(chr((number & 0x7F) | flag)) - flag = 0x80 - number >>= 7 - shape.append(chr(number | flag)) - - def add_ebp_offset(self, shape, offset): - assert (offset & 3) == 0 - if offset >= 0: - num = self.LOC_EBP_PLUS | offset - else: - num = self.LOC_EBP_MINUS | (-offset) - self._encode_num(shape, num) - - def add_ebx(self, shape): - shape.append(chr(self.LOC_REG | 4)) - def add_esi(self, shape): - shape.append(chr(self.LOC_REG | 8)) - - def add_edi(self, shape): - shape.append(chr(self.LOC_REG | 12)) - - def add_ebp(self, shape): - shape.append(chr(self.LOC_REG | 16)) - - def compress_callshape(self, shape): - # Similar to compress_callshape() in trackgcroot.py. - # XXX so far, we always allocate a new small array (we could regroup - # them inside bigger arrays) and we never try to share them. - length = len(shape) - compressed = lltype.malloc(self.CALLSHAPE_ARRAY, length, - flavor='raw') - for i in range(length): - compressed[length-1-i] = rffi.cast(rffi.UCHAR, shape[i]) - return llmemory.cast_ptr_to_adr(compressed) - - -class WriteBarrierDescr(AbstractDescr): - def __init__(self, gc_ll_descr): - self.llop1 = gc_ll_descr.llop1 - self.WB_FUNCPTR = gc_ll_descr.WB_FUNCPTR - self.fielddescr_tid = get_field_descr(gc_ll_descr, - gc_ll_descr.GCClass.HDR, 'tid') - self.jit_wb_if_flag = gc_ll_descr.GCClass.JIT_WB_IF_FLAG - # if convenient for the backend, we also compute the info about - # the flag as (byte-offset, single-byte-flag). - import struct - value = struct.pack("i", self.jit_wb_if_flag) - assert value.count('\x00') == len(value) - 1 # only one byte is != 0 - i = 0 - while value[i] == '\x00': i += 1 - self.jit_wb_if_flag_byteofs = i - self.jit_wb_if_flag_singlebyte = struct.unpack('b', value[i])[0] - - def get_write_barrier_fn(self, cpu): - llop1 = self.llop1 - funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcaddr = llmemory.cast_ptr_to_adr(funcptr) - return cpu.cast_adr_to_int(funcaddr) - - -class GcLLDescr_framework(GcLLDescription): - - def __init__(self, gcdescr, translator, llop1=llop): - from pypy.rpython.memory.gctypelayout import _check_typeid - from pypy.rpython.memory.gcheader import GCHeaderBuilder - from pypy.rpython.memory.gctransform import framework - GcLLDescription.__init__(self, gcdescr, translator) - assert self.translate_support_code, "required with the framework GC" - self.translator = translator - self.llop1 = llop1 - - # we need the hybrid GC for GcRefList.alloc_gcref_list() to work - if gcdescr.config.translation.gc != 'hybrid': - raise NotImplementedError("--gc=%s not implemented with the JIT" % - (gcdescr.config.translation.gc,)) - - # to find roots in the assembler, make a GcRootMap - name = gcdescr.config.translation.gcrootfinder - try: - cls = globals()['GcRootMap_' + name] - except KeyError: - raise NotImplementedError("--gcrootfinder=%s not implemented" - " with the JIT" % (name,)) - gcrootmap = cls() - self.gcrootmap = gcrootmap - self.gcrefs = GcRefList() - self.single_gcref_descr = GcPtrFieldDescr(0) - - # make a TransformerLayoutBuilder and save it on the translator - # where it can be fished and reused by the FrameworkGCTransformer - self.layoutbuilder = framework.TransformerLayoutBuilder(translator) - self.layoutbuilder.delay_encoding() - self.translator._jit2gc = { - 'layoutbuilder': self.layoutbuilder, - 'gcmapstart': lambda: gcrootmap.gcmapstart(), - 'gcmapend': lambda: gcrootmap.gcmapend(), - } - self.GCClass = self.layoutbuilder.GCClass - self.moving_gc = self.GCClass.moving_gc - self.HDRPTR = lltype.Ptr(self.GCClass.HDR) - self.gcheaderbuilder = GCHeaderBuilder(self.HDRPTR.TO) - (self.array_basesize, _, self.array_length_ofs) = \ - symbolic.get_array_token(lltype.GcArray(lltype.Signed), True) - min_ns = self.GCClass.TRANSLATION_PARAMS['min_nursery_size'] - self.max_size_of_young_obj = self.GCClass.get_young_fixedsize(min_ns) - - # make a malloc function, with three arguments - def malloc_basic(size, tid): - type_id = llop.extract_ushort(rffi.USHORT, tid) - has_finalizer = bool(tid & (1<<16)) - _check_typeid(type_id) - try: - res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, - type_id, size, True, - has_finalizer, False) - except MemoryError: - fatalerror("out of memory (from JITted code)") - res = lltype.nullptr(llmemory.GCREF.TO) - #llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id, - # "-->", res) - return res - self.malloc_basic = malloc_basic - self.GC_MALLOC_BASIC = lltype.Ptr(lltype.FuncType( - [lltype.Signed, lltype.Signed], llmemory.GCREF)) - self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType( - [llmemory.Address, llmemory.Address], lltype.Void)) - self.write_barrier_descr = WriteBarrierDescr(self) - # - def malloc_array(itemsize, tid, num_elem): - type_id = llop.extract_ushort(rffi.USHORT, tid) - _check_typeid(type_id) - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - type_id, num_elem, self.array_basesize, itemsize, - self.array_length_ofs, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) - self.malloc_array = malloc_array - self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType( - [lltype.Signed] * 3, llmemory.GCREF)) - # - (str_basesize, str_itemsize, str_ofs_length - ) = symbolic.get_array_token(rstr.STR, True) - (unicode_basesize, unicode_itemsize, unicode_ofs_length - ) = symbolic.get_array_token(rstr.UNICODE, True) - str_type_id = self.layoutbuilder.get_type_id(rstr.STR) - unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE) - # - def malloc_str(length): - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - str_type_id, length, str_basesize, str_itemsize, - str_ofs_length, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) - def malloc_unicode(length): - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - unicode_type_id, length, unicode_basesize,unicode_itemsize, - unicode_ofs_length, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) - self.malloc_str = malloc_str - self.malloc_unicode = malloc_unicode - self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType( - [lltype.Signed], llmemory.GCREF)) - def malloc_fixedsize_slowpath(size): - try: - gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, - 0, size, True, False, False) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return r_ulonglong(0) - res = rffi.cast(lltype.Signed, gcref) - nurs_free = llop1.gc_adr_of_nursery_free(llmemory.Address).signed[0] - return r_ulonglong(nurs_free) << 32 | r_ulonglong(r_uint(res)) - self.malloc_fixedsize_slowpath = malloc_fixedsize_slowpath - self.MALLOC_FIXEDSIZE_SLOWPATH = lltype.FuncType([lltype.Signed], - lltype.UnsignedLongLong) - - def get_nursery_free_addr(self): - nurs_addr = llop.gc_adr_of_nursery_free(llmemory.Address) - return rffi.cast(lltype.Signed, nurs_addr) - - def get_nursery_top_addr(self): - nurs_top_addr = llop.gc_adr_of_nursery_top(llmemory.Address) - return rffi.cast(lltype.Signed, nurs_top_addr) - - def get_malloc_fixedsize_slowpath_addr(self): - fptr = llhelper(lltype.Ptr(self.MALLOC_FIXEDSIZE_SLOWPATH), - self.malloc_fixedsize_slowpath) - return rffi.cast(lltype.Signed, fptr) - - def initialize(self): - self.gcrefs.initialize() - self.gcrootmap.initialize() - - def init_size_descr(self, S, descr): - type_id = self.layoutbuilder.get_type_id(S) - assert not self.layoutbuilder.is_weakref(type_id) - has_finalizer = bool(self.layoutbuilder.has_finalizer(S)) - flags = int(has_finalizer) << 16 - descr.tid = llop.combine_ushort(lltype.Signed, type_id, flags) - - def init_array_descr(self, A, descr): - type_id = self.layoutbuilder.get_type_id(A) - descr.tid = llop.combine_ushort(lltype.Signed, type_id, 0) - - def gc_malloc(self, sizedescr): - assert isinstance(sizedescr, BaseSizeDescr) - return self.malloc_basic(sizedescr.size, sizedescr.tid) - - def gc_malloc_array(self, arraydescr, num_elem): - assert isinstance(arraydescr, BaseArrayDescr) - itemsize = arraydescr.get_item_size(self.translate_support_code) - return self.malloc_array(itemsize, arraydescr.tid, num_elem) - - def gc_malloc_str(self, num_elem): - return self.malloc_str(num_elem) - - def gc_malloc_unicode(self, num_elem): - return self.malloc_unicode(num_elem) - - def args_for_new(self, sizedescr): - assert isinstance(sizedescr, BaseSizeDescr) - return [sizedescr.size, sizedescr.tid] - - def args_for_new_array(self, arraydescr): - assert isinstance(arraydescr, BaseArrayDescr) - itemsize = arraydescr.get_item_size(self.translate_support_code) - return [itemsize, arraydescr.tid] - - def get_funcptr_for_new(self): - return llhelper(self.GC_MALLOC_BASIC, self.malloc_basic) - - def get_funcptr_for_newarray(self): - return llhelper(self.GC_MALLOC_ARRAY, self.malloc_array) - - def get_funcptr_for_newstr(self): - return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_str) - - def get_funcptr_for_newunicode(self): - return llhelper(self.GC_MALLOC_STR_UNICODE, self.malloc_unicode) - - def do_write_barrier(self, gcref_struct, gcref_newptr): - hdr_addr = llmemory.cast_ptr_to_adr(gcref_struct) - hdr_addr -= self.gcheaderbuilder.size_gc_header - hdr = llmemory.cast_adr_to_ptr(hdr_addr, self.HDRPTR) - if hdr.tid & self.GCClass.JIT_WB_IF_FLAG: - # get a pointer to the 'remember_young_pointer' function from - # the GC, and call it immediately - llop1 = self.llop1 - funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR) - funcptr(llmemory.cast_ptr_to_adr(gcref_struct), - llmemory.cast_ptr_to_adr(gcref_newptr)) - - def rewrite_assembler(self, cpu, operations): - # Perform two kinds of rewrites in parallel: - # - # - Add COND_CALLs to the write barrier before SETFIELD_GC and - # SETARRAYITEM_GC operations. - # - # - Remove all uses of ConstPtrs away from the assembler. - # Idea: when running on a moving GC, we can't (easily) encode - # the ConstPtrs in the assembler, because they can move at any - # point in time. Instead, we store them in 'gcrefs.list', a GC - # but nonmovable list; and here, we modify 'operations' to - # replace direct usage of ConstPtr with a BoxPtr loaded by a - # GETFIELD_RAW from the array 'gcrefs.list'. - # - newops = [] - for op in operations: - if op.opnum == rop.DEBUG_MERGE_POINT: - continue - # ---------- replace ConstPtrs with GETFIELD_RAW ---------- - # xxx some performance issue here - for i in range(len(op.args)): - v = op.args[i] - if isinstance(v, ConstPtr) and bool(v.value): - addr = self.gcrefs.get_address_of_gcref(v.value) - # ^^^even for non-movable objects, to record their presence - if rgc.can_move(v.value): - box = BoxPtr(v.value) - addr = cpu.cast_adr_to_int(addr) - newops.append(ResOperation(rop.GETFIELD_RAW, - [ConstInt(addr)], box, - self.single_gcref_descr)) - op.args[i] = box - # ---------- write barrier for SETFIELD_GC ---------- - if op.opnum == rop.SETFIELD_GC: - v = op.args[1] - if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and - bool(v.value)): # store a non-NULL - self._gen_write_barrier(newops, op.args[0], v) - op = ResOperation(rop.SETFIELD_RAW, op.args, None, - descr=op.descr) - # ---------- write barrier for SETARRAYITEM_GC ---------- - if op.opnum == rop.SETARRAYITEM_GC: - v = op.args[2] - if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and - bool(v.value)): # store a non-NULL - self._gen_write_barrier(newops, op.args[0], v) - op = ResOperation(rop.SETARRAYITEM_RAW, op.args, None, - descr=op.descr) - # ---------- - newops.append(op) - del operations[:] - operations.extend(newops) - - def _gen_write_barrier(self, newops, v_base, v_value): - args = [v_base, v_value] - newops.append(ResOperation(rop.COND_CALL_GC_WB, args, None, - descr=self.write_barrier_descr)) - - def can_inline_malloc(self, descr): - assert isinstance(descr, BaseSizeDescr) - if descr.size < self.max_size_of_young_obj: - has_finalizer = bool(descr.tid & (1<<16)) - if has_finalizer: - return False - return True - return False - - def has_write_barrier_class(self): - return WriteBarrierDescr +def GcLLDescr_framework(*args): + from pypy.jit.backend.llsupport import gcframework + return gcframework.GcLLDescr_framework(*args) # ____________________________________________________________ Copied: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py (from r71876, pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py) ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py Mon Mar 8 16:22:14 2010 @@ -1,201 +1,82 @@ -from pypy.rlib import rgc -from pypy.rlib.objectmodel import we_are_translated +from pypy.jit.backend.llsupport.gc import GcLLDescription from pypy.rlib.debug import fatalerror -from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper -from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, ConstPtr +from pypy.jit.metainterp.history import BoxPtr, ConstPtr from pypy.jit.metainterp.history import AbstractDescr from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.backend.llsupport import symbolic -from pypy.jit.backend.llsupport.symbolic import WORD from pypy.jit.backend.llsupport.descr import BaseSizeDescr, BaseArrayDescr -from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr +from pypy.jit.backend.llsupport.descr import get_field_descr from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr from pypy.jit.backend.llsupport.descr import get_call_descr from pypy.rlib.rarithmetic import r_ulonglong, r_uint -# ____________________________________________________________ - -class GcLLDescription(GcCache): - def __init__(self, gcdescr, translator=None): - GcCache.__init__(self, translator is not None) - self.gcdescr = gcdescr - def _freeze_(self): - return True - def initialize(self): - pass - def do_write_barrier(self, gcref_struct, gcref_newptr): - pass - def rewrite_assembler(self, cpu, operations): - pass - def can_inline_malloc(self, descr): - return False - def has_write_barrier_class(self): - return None - -# ____________________________________________________________ - -class GcLLDescr_boehm(GcLLDescription): - moving_gc = False - gcrootmap = None - - def __init__(self, gcdescr, translator): - GcLLDescription.__init__(self, gcdescr, translator) - # grab a pointer to the Boehm 'malloc' function - from pypy.rpython.tool import rffi_platform - compilation_info = rffi_platform.configure_boehm() - - # Versions 6.x of libgc needs to use GC_local_malloc(). - # Versions 7.x of libgc removed this function; GC_malloc() has - # the same behavior if libgc was compiled with - # THREAD_LOCAL_ALLOC. - class CConfig: - _compilation_info_ = compilation_info - HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc") - config = rffi_platform.configure(CConfig) - if config['HAS_LOCAL_MALLOC']: - GC_MALLOC = "GC_local_malloc" - else: - GC_MALLOC = "GC_malloc" - - malloc_fn_ptr = rffi.llexternal(GC_MALLOC, - [lltype.Signed], # size_t, but good enough - llmemory.GCREF, - compilation_info=compilation_info, - sandboxsafe=True, - _nowrapper=True) - self.funcptr_for_new = malloc_fn_ptr - - # on some platform GC_init is required before any other - # GC_* functions, call it here for the benefit of tests - # XXX move this to tests - init_fn_ptr = rffi.llexternal("GC_init", - [], lltype.Void, - compilation_info=compilation_info, - sandboxsafe=True, - _nowrapper=True) - - init_fn_ptr() - - def gc_malloc(self, sizedescr): - assert isinstance(sizedescr, BaseSizeDescr) - return self.funcptr_for_new(sizedescr.size) - - def gc_malloc_array(self, arraydescr, num_elem): - assert isinstance(arraydescr, BaseArrayDescr) - ofs_length = arraydescr.get_ofs_length(self.translate_support_code) - basesize = arraydescr.get_base_size(self.translate_support_code) - itemsize = arraydescr.get_item_size(self.translate_support_code) - size = basesize + itemsize * num_elem - res = self.funcptr_for_new(size) - rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem - return res - - def gc_malloc_str(self, num_elem): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, - self.translate_support_code) - assert itemsize == 1 - size = basesize + num_elem - res = self.funcptr_for_new(size) - rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem - return res - - def gc_malloc_unicode(self, num_elem): - basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE, - self.translate_support_code) - size = basesize + num_elem * itemsize - res = self.funcptr_for_new(size) - rffi.cast(rffi.CArrayPtr(lltype.Signed), res)[ofs_length/WORD] = num_elem - return res - - def args_for_new(self, sizedescr): - assert isinstance(sizedescr, BaseSizeDescr) - return [sizedescr.size] - - def get_funcptr_for_new(self): - return self.funcptr_for_new - - get_funcptr_for_newarray = None - get_funcptr_for_newstr = None - get_funcptr_for_newunicode = None +from pypy.rpython.memory import gctypelayout +from pypy.rpython.memory.gctypelayout import _check_typeid +from pypy.rpython.memory.gcheader import GCHeaderBuilder +from pypy.rpython.memory.gctransform import framework # ____________________________________________________________ -# All code below is for the hybrid GC +# All code below is for our framework GCs -class GcRefList: - """Handles all references from the generated assembler to GC objects. - This is implemented as a nonmovable, but GC, list; the assembler contains - code that will (for now) always read from this list.""" - - GCREF_LIST = lltype.GcArray(llmemory.GCREF) # followed by the GC - - HASHTABLE = rffi.CArray(llmemory.Address) # ignored by the GC - HASHTABLE_BITS = 10 - HASHTABLE_SIZE = 1 << HASHTABLE_BITS +class GcRefHandler: + """Handles all constant GCREFs stored in the assembler. + This includes the fact that some of these constants may end up stored + with an extra offset, e.g. as the address out of which a GETFIELD_GC + on them should fetch data. + """ + CONSTGCREF_ARRAY = lltype.GcArray(("gcref", llmemory.GCREF), + ("addr", llmemory.Address)) + gcrefarray_lengthoffset = llmemory.ArrayLengthOffset(CONSTGCREF_ARRAY) + gcrefarray_itemsoffset = llmemory.ArrayItemsOffset(CONSTGCREF_ARRAY) + gcrefarray_singleitemoffset = llmemory.ItemOffset(CONSTGCREF_ARRAY.OF) + gcrefarrayitem_gcref = llmemory.offsetof(CONSTGCREF_ARRAY.OF, "gcref") + gcrefarrayitem_addr = llmemory.offsetof(CONSTGCREF_ARRAY.OF, "addr") + + def __init__(self, layoutbuilder): + self.constgcref_array_type_id = layoutbuilder.get_type_id( + self.CONSTGCREF_ARRAY) - def initialize(self): - if we_are_translated(): n = 2000 - else: n = 10 # tests only - self.list = self.alloc_gcref_list(n) - self.nextindex = 0 - self.oldlists = [] - # A pseudo dictionary: it is fixed size, and it may contain - # random nonsense after a collection moved the objects. It is only - # used to avoid too many duplications in the GCREF_LISTs. - self.hashtable = lltype.malloc(self.HASHTABLE, - self.HASHTABLE_SIZE+1, - flavor='raw') - dummy = lltype.direct_ptradd(lltype.direct_arrayitems(self.hashtable), - self.HASHTABLE_SIZE) - dummy = llmemory.cast_ptr_to_adr(dummy) - for i in range(self.HASHTABLE_SIZE+1): - self.hashtable[i] = dummy - - def alloc_gcref_list(self, n): - # Important: the GRREF_LISTs allocated are *non-movable*. This - # requires support in the gc (only the hybrid GC supports it so far). - if we_are_translated(): - list = rgc.malloc_nonmovable(self.GCREF_LIST, n) - assert list, "malloc_nonmovable failed!" - else: - list = lltype.malloc(self.GCREF_LIST, n) # for tests only - return list + def _freeze_(self): + return True - def get_address_of_gcref(self, gcref): - assert lltype.typeOf(gcref) == llmemory.GCREF - # first look in the hashtable, using an inexact hash (fails after - # the object moves) - addr = llmemory.cast_ptr_to_adr(gcref) - hash = llmemory.cast_adr_to_int(addr) - hash -= hash >> self.HASHTABLE_BITS - hash &= self.HASHTABLE_SIZE - 1 - addr_ref = self.hashtable[hash] - # the following test is safe anyway, because the addresses found - # in the hashtable are always the addresses of nonmovable stuff - # ('addr_ref' is an address inside self.list, not directly the - # address of a real moving GC object -- that's 'addr_ref.address[0]'.) - if addr_ref.address[0] == addr: - return addr_ref - # if it fails, add an entry to the list - if self.nextindex == len(self.list): - # reallocate first, increasing a bit the size every time - self.oldlists.append(self.list) - self.list = self.alloc_gcref_list(len(self.list) // 4 * 5) - self.nextindex = 0 - # add it - index = self.nextindex - self.list[index] = gcref - addr_ref = lltype.direct_ptradd(lltype.direct_arrayitems(self.list), - index) - addr_ref = llmemory.cast_ptr_to_adr(addr_ref) - self.nextindex = index + 1 - # record it in the hashtable - self.hashtable[hash] = addr_ref - return addr_ref + def start_tracing_varsized_part(self, obj, typeid): + """Called by the GC just before tracing the object 'obj'.""" + if typeid == self.constgcref_array_type_id: + self.do_start_stop_tracing(obj, False) + + def stop_tracing_varsized_part(self, obj, typeid): + """Called by the GC just after tracing the object 'obj'.""" + if typeid == self.constgcref_array_type_id: + self.do_start_stop_tracing(obj, True) + + def do_start_stop_tracing(self, obj, done): + # Before tracing an object of type CONSTGCREF_ARRAY + # (done=False), we take all addresses in the assembler and + # subtract the gcref from them. This leaves the assembler in a + # broken state which is fixed by do_stop_tracing(). The numbers + # in the assembler now are just the offsets from the start of + # the objects. After tracing (done=True), we add again the + # gcrefs to the addresses in the assembler, fixing up the + # numbers. + length = (obj + self.gcrefarray_lengthoffset).signed[0] + item = obj + self.gcrefarray_itemsoffset + while length > 0: + gcref = (item + self.gcrefarrayitem_gcref).address[0] + addr = (item + self.gcrefarrayitem_addr).address[0] + gcref = llmemory.cast_adr_to_int(gcref) + if done: + addr.signed[0] += gcref + else: + addr.signed[0] -= gcref + item += self.gcrefarray_singleitemoffset + length -= 1 + do_start_stop_tracing._dont_inline_ = True + do_start_stop_tracing._annspecialcase_ = 'specialize:arg(2)' class GcRootMap_asmgcc: @@ -327,19 +208,11 @@ class GcLLDescr_framework(GcLLDescription): def __init__(self, gcdescr, translator, llop1=llop): - from pypy.rpython.memory.gctypelayout import _check_typeid - from pypy.rpython.memory.gcheader import GCHeaderBuilder - from pypy.rpython.memory.gctransform import framework GcLLDescription.__init__(self, gcdescr, translator) assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 - # we need the hybrid GC for GcRefList.alloc_gcref_list() to work - if gcdescr.config.translation.gc != 'hybrid': - raise NotImplementedError("--gc=%s not implemented with the JIT" % - (gcdescr.config.translation.gc,)) - # to find roots in the assembler, make a GcRootMap name = gcdescr.config.translation.gcrootfinder try: @@ -349,17 +222,20 @@ " with the JIT" % (name,)) gcrootmap = cls() self.gcrootmap = gcrootmap - self.gcrefs = GcRefList() - self.single_gcref_descr = GcPtrFieldDescr(0) # make a TransformerLayoutBuilder and save it on the translator # where it can be fished and reused by the FrameworkGCTransformer self.layoutbuilder = framework.TransformerLayoutBuilder(translator) self.layoutbuilder.delay_encoding() + self.gcrefhandler = GcRefHandler(self.layoutbuilder) self.translator._jit2gc = { 'layoutbuilder': self.layoutbuilder, 'gcmapstart': lambda: gcrootmap.gcmapstart(), 'gcmapend': lambda: gcrootmap.gcmapend(), + 'start_tracing_varsized_part': + self.gcrefhandler.start_tracing_varsized_part, + 'stop_tracing_varsized_part': + self.gcrefhandler.stop_tracing_varsized_part, } self.GCClass = self.layoutbuilder.GCClass self.moving_gc = self.GCClass.moving_gc @@ -464,7 +340,6 @@ return rffi.cast(lltype.Signed, fptr) def initialize(self): - self.gcrefs.initialize() self.gcrootmap.initialize() def init_size_descr(self, S, descr): @@ -532,31 +407,26 @@ # - Add COND_CALLs to the write barrier before SETFIELD_GC and # SETARRAYITEM_GC operations. # - # - Remove all uses of ConstPtrs away from the assembler. - # Idea: when running on a moving GC, we can't (easily) encode - # the ConstPtrs in the assembler, because they can move at any - # point in time. Instead, we store them in 'gcrefs.list', a GC - # but nonmovable list; and here, we modify 'operations' to - # replace direct usage of ConstPtr with a BoxPtr loaded by a - # GETFIELD_RAW from the array 'gcrefs.list'. + # - Remove "unsupported" uses of ConstPtrs away from the assembler. + # The backend must support at least 'p = SAME_AS(ConstPtr(..))' + # and might support more operations, like GETFIELD_GC. It should + # set GC_SUPPORTED_CONSTPTR to a dict of supported opnums. + # Or, as in the x86 backend, it can directly support all usages of + # ConstPtr and not need any rewrite at all (and then it should + # set GC_SUPPORTED_CONSTPTR to True). # newops = [] for op in operations: if op.opnum == rop.DEBUG_MERGE_POINT: continue - # ---------- replace ConstPtrs with GETFIELD_RAW ---------- - # xxx some performance issue here - for i in range(len(op.args)): - v = op.args[i] - if isinstance(v, ConstPtr) and bool(v.value): - addr = self.gcrefs.get_address_of_gcref(v.value) - # ^^^even for non-movable objects, to record their presence - if rgc.can_move(v.value): + # ---------- replace ConstPtrs with SAME_AS ---------- + if (cpu.GC_SUPPORTED_CONSTPTR is not True and + op.opnum not in cpu.GC_SUPPORTED_CONSTPTR): + for i in range(len(op.args)): + v = op.args[i] + if isinstance(v, ConstPtr) and bool(v.value): box = BoxPtr(v.value) - addr = cpu.cast_adr_to_int(addr) - newops.append(ResOperation(rop.GETFIELD_RAW, - [ConstInt(addr)], box, - self.single_gcref_descr)) + newops.append(ResOperation(rop.SAME_AS, [v], box)) op.args[i] = box # ---------- write barrier for SETFIELD_GC ---------- if op.opnum == rop.SETFIELD_GC: @@ -595,18 +465,3 @@ def has_write_barrier_class(self): return WriteBarrierDescr - -# ____________________________________________________________ - -def get_ll_description(gcdescr, translator=None): - # translator is None if translate_support_code is False. - if gcdescr is not None: - name = gcdescr.config.translation.gctransformer - else: - name = "boehm" - try: - cls = globals()['GcLLDescr_' + name] - except KeyError: - raise NotImplementedError("GC transformer %r not supported by " - "the JIT backend" % (name,)) - return cls(gcdescr, translator) Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py Mon Mar 8 16:22:14 2010 @@ -4,6 +4,7 @@ from pypy.rpython.annlowlevel import llhelper from pypy.jit.backend.llsupport.descr import * from pypy.jit.backend.llsupport.gc import * +from pypy.jit.backend.llsupport.gcframework import * from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.gc import get_description @@ -46,19 +47,44 @@ # ____________________________________________________________ -def test_GcRefList(): +def test_GcRefHandler(): + class FakeLayoutBuilder: + def get_type_id(self, TYPE): + return 42 + gcrefhandler = GcRefHandler(FakeLayoutBuilder()) + gcrefhandler.start_tracing_varsized_part(None, 27) # no effect + gcrefhandler.stop_tracing_varsized_part(None, 27) # no effect + # S = lltype.GcStruct('S') - order = range(50) * 4 - random.shuffle(order) - allocs = [lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) - for i in range(50)] - allocs = [allocs[i] for i in order] + p0 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) + p1 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) + p = lltype.malloc(GcRefHandler.CONSTGCREF_ARRAY, 3) + # + ARRAY_SIGNED = lltype.Array(lltype.Signed) + test = lltype.malloc(ARRAY_SIGNED, 5, immortal=True) + test[2] = 123 + test[3] = 456 + test[4] = 789 + # + p[0].gcref = p0 + p[0].addr = (llmemory.cast_ptr_to_adr(test) + + llmemory.itemoffsetof(ARRAY_SIGNED, 2)) + p[1].gcref = p0 + p[1].addr = (llmemory.cast_ptr_to_adr(test) + + llmemory.itemoffsetof(ARRAY_SIGNED, 4)) + p[2].gcref = p1 + p[2].addr = (llmemory.cast_ptr_to_adr(test) + + llmemory.itemoffsetof(ARRAY_SIGNED, 3)) + # + gcrefhandler.start_tracing_varsized_part(llmemory.cast_ptr_to_adr(p), 42) + assert test[2] == 123 - llmemory.cast_adr_to_int(p0) + assert test[3] == 456 - llmemory.cast_adr_to_int(p1) + assert test[4] == 789 - llmemory.cast_adr_to_int(p0) # - gcrefs = GcRefList() - gcrefs.initialize() - addrs = [gcrefs.get_address_of_gcref(ptr) for ptr in allocs] - for i in range(len(allocs)): - assert addrs[i].address[0] == llmemory.cast_ptr_to_adr(allocs[i]) + gcrefhandler.stop_tracing_varsized_part(llmemory.cast_ptr_to_adr(p), 42) + assert test[2] == 123 + assert test[3] == 456 + assert test[4] == 789 def test_GcRootMap_asmgcc(): def frame_pos(n): @@ -160,10 +186,7 @@ class FakeTranslator: config = config_ class FakeCPU: - def cast_adr_to_int(self, adr): - ptr = llmemory.cast_adr_to_ptr(adr, gc_ll_descr.WB_FUNCPTR) - assert ptr._obj._callable == llop1._write_barrier_failing_case - return 42 + GC_SUPPORTED_CONSTPTR = {rop.SAME_AS: None} gcdescr = get_description(config_) translator = FakeTranslator() llop1 = FakeLLOp() @@ -277,46 +300,40 @@ def test_rewrite_assembler_1(self): # check rewriting of ConstPtrs class MyFakeCPU: - def cast_adr_to_int(self, adr): - assert adr == "some fake address" - return 43 - class MyFakeGCRefList: - def get_address_of_gcref(self, s_gcref1): - assert s_gcref1 == s_gcref - return "some fake address" + GC_SUPPORTED_CONSTPTR = {rop.SAME_AS: None, + rop.OOISNOT: None} S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) + s2 = lltype.malloc(S) + s_gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s2) v_random_box = BoxPtr() v_result = BoxInt() + v_result2 = BoxInt() operations = [ ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)], v_result), + ResOperation(rop.OOISNOT, [v_random_box, ConstPtr(s_gcref2)], + v_result2), ] gc_ll_descr = self.gc_ll_descr - gc_ll_descr.gcrefs = MyFakeGCRefList() gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) - assert len(operations) == 2 - assert operations[0].opnum == rop.GETFIELD_RAW - assert operations[0].args == [ConstInt(43)] - assert operations[0].descr == gc_ll_descr.single_gcref_descr + assert len(operations) == 3 + assert operations[0].opnum == rop.SAME_AS + assert operations[0].args == [ConstPtr(s_gcref)] v_box = operations[0].result assert isinstance(v_box, BoxPtr) assert operations[1].opnum == rop.OOIS assert operations[1].args == [v_random_box, v_box] assert operations[1].result == v_result + assert operations[2].opnum == rop.OOISNOT + assert operations[2].args == [v_random_box, ConstPtr(s_gcref2)] + assert operations[2].result == v_result2 - def test_rewrite_assembler_1_cannot_move(self): - # check rewriting of ConstPtrs + def test_rewrite_assembler_1_all_supported(self): + # check no rewriting of ConstPtrs if the cpu supports it fully class MyFakeCPU: - def cast_adr_to_int(self, adr): - xxx # should not be called - class MyFakeGCRefList: - def get_address_of_gcref(self, s_gcref1): - seen.append(s_gcref1) - assert s_gcref1 == s_gcref - return "some fake address" - seen = [] + GC_SUPPORTED_CONSTPTR = True S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) @@ -327,20 +344,11 @@ v_result), ] gc_ll_descr = self.gc_ll_descr - gc_ll_descr.gcrefs = MyFakeGCRefList() - old_can_move = rgc.can_move - try: - rgc.can_move = lambda s: False - gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) - finally: - rgc.can_move = old_can_move + gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) assert len(operations) == 1 assert operations[0].opnum == rop.OOIS assert operations[0].args == [v_random_box, ConstPtr(s_gcref)] assert operations[0].result == v_result - # check that s_gcref gets added to the list anyway, to make sure - # that the GC sees it - assert seen == [s_gcref] def test_rewrite_assembler_2(self): # check write barriers before SETFIELD_GC Modified: pypy/branch/jit-constptr/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/x86/runner.py Mon Mar 8 16:22:14 2010 @@ -13,6 +13,7 @@ class CPU386(AbstractLLCPU): debug = True supports_floats = True + GC_SUPPORTED_CONSTPTR = True BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed) dont_keepalive_stuff = False # for tests Modified: pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py Mon Mar 8 16:22:14 2010 @@ -14,7 +14,6 @@ from pypy.rlib.jit import JitDriver, OPTIMIZER_SIMPLE, dont_look_inside from pypy.rlib.jit import purefunction from pypy.jit.backend.x86.runner import CPU386 -from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc from pypy.tool.udir import udir class X(object): Modified: pypy/branch/jit-constptr/pypy/rpython/memory/gc/base.py ============================================================================== --- pypy/branch/jit-constptr/pypy/rpython/memory/gc/base.py (original) +++ pypy/branch/jit-constptr/pypy/rpython/memory/gc/base.py Mon Mar 8 16:22:14 2010 @@ -25,6 +25,9 @@ self.AddressDeque = get_address_deque(chunk_size) self.AddressDict = AddressDict self.config = config + # hooks used by the JIT: + self.start_tracing_varsized_part = lambda obj, typeid: None + self.stop_tracing_varsized_part = lambda obj, typeid: None def setup(self): # all runtime mutable values' setup should happen here @@ -177,6 +180,7 @@ callback(item, arg) i += 1 if self.has_gcptr_in_varsize(typeid): + self.start_tracing_varsized_part(obj, 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) @@ -190,6 +194,7 @@ j += 1 item += itemlength length -= 1 + self.stop_tracing_varsized_part(obj, typeid) trace._annspecialcase_ = 'specialize:arg(2)' def points_to_valid_gc_object(self, addr): Modified: pypy/branch/jit-constptr/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/branch/jit-constptr/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/branch/jit-constptr/pypy/rpython/memory/gctransform/framework.py Mon Mar 8 16:22:14 2010 @@ -181,6 +181,12 @@ self.num_pushs = 0 self.write_barrier_calls = 0 + if hasattr(translator, '_jit2gc'): + fn = translator._jit2gc['start_tracing_varsized_part'] + gcdata.gc.start_tracing_varsized_part = fn + fn = translator._jit2gc['stop_tracing_varsized_part'] + gcdata.gc.stop_tracing_varsized_part = fn + def frameworkgc_setup(): # run-time initialization code root_walker.setup_root_walker() From arigo at codespeak.net Mon Mar 8 16:43:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 16:43:51 +0100 (CET) Subject: [pypy-svn] r71886 - in pypy/branch/jit-constptr/pypy/jit/backend/llsupport: . test Message-ID: <20100308154351.E124851056@codespeak.net> Author: arigo Date: Mon Mar 8 16:43:50 2010 New Revision: 71886 Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py Log: Tweaks, documentation, and kill unused code. Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py Mon Mar 8 16:43:50 2010 @@ -29,6 +29,14 @@ with an extra offset, e.g. as the address out of which a GETFIELD_GC on them should fetch data. """ + # The idea is to store in an array of type CONSTGCREF_ARRAY a list + # of pairs (gcref, addr), where 'gcref' is some GC-tracked object, + # and 'addr' is the address in the assembler where 'gcref' was used. + # This usually means that 'gcref' is currently stored at 'addr', but + # it may also be the case that there is a small offset; e.g. a + # GETFIELD_GC(ConstPtr(0x123450), descr=) will end up as + # an assembler instruction like MOV EAX, [0x123458]. + # CONSTGCREF_ARRAY = lltype.GcArray(("gcref", llmemory.GCREF), ("addr", llmemory.Address)) gcrefarray_lengthoffset = llmemory.ArrayLengthOffset(CONSTGCREF_ARRAY) @@ -40,39 +48,46 @@ def __init__(self, layoutbuilder): self.constgcref_array_type_id = layoutbuilder.get_type_id( self.CONSTGCREF_ARRAY) + self.full_constgcref_array_type_id = llop.combine_ushort( + lltype.Signed, + self.constgcref_array_type_id, + 0) def _freeze_(self): return True def start_tracing_varsized_part(self, obj, typeid): """Called by the GC just before tracing the object 'obj'.""" - if typeid == self.constgcref_array_type_id: + fulltypeid = llop.combine_ushort(lltype.Signed, typeid, 0) + if fulltypeid == self.full_constgcref_array_type_id: self.do_start_stop_tracing(obj, False) def stop_tracing_varsized_part(self, obj, typeid): """Called by the GC just after tracing the object 'obj'.""" - if typeid == self.constgcref_array_type_id: + fulltypeid = llop.combine_ushort(lltype.Signed, typeid, 0) + if fulltypeid == self.full_constgcref_array_type_id: self.do_start_stop_tracing(obj, True) def do_start_stop_tracing(self, obj, done): # Before tracing an object of type CONSTGCREF_ARRAY # (done=False), we take all addresses in the assembler and - # subtract the gcref from them. This leaves the assembler in a - # broken state which is fixed by do_stop_tracing(). The numbers - # in the assembler now are just the offsets from the start of - # the objects. After tracing (done=True), we add again the - # gcrefs to the addresses in the assembler, fixing up the - # numbers. + # subtract the gcrefs from them. This leaves the assembler in a + # broken state: the numbers in the assembler now are just the + # offsets from the start of the objects. After tracing + # (done=True), we add again the gcrefs to the addresses in the + # assembler, fixing up the numbers. For any object that moved, + # that object's address in the assembler is now fixed. length = (obj + self.gcrefarray_lengthoffset).signed[0] item = obj + self.gcrefarray_itemsoffset while length > 0: gcref = (item + self.gcrefarrayitem_gcref).address[0] - addr = (item + self.gcrefarrayitem_addr).address[0] - gcref = llmemory.cast_adr_to_int(gcref) - if done: - addr.signed[0] += gcref - else: - addr.signed[0] -= gcref + if gcref: + gcref = llmemory.cast_adr_to_int(gcref) + addr = (item + self.gcrefarrayitem_addr).address[0] + if done: + addr.signed[0] += gcref + else: + addr.signed[0] -= gcref item += self.gcrefarray_singleitemoffset length -= 1 do_start_stop_tracing._dont_inline_ = True @@ -402,32 +417,12 @@ llmemory.cast_ptr_to_adr(gcref_newptr)) def rewrite_assembler(self, cpu, operations): - # Perform two kinds of rewrites in parallel: - # - # - Add COND_CALLs to the write barrier before SETFIELD_GC and - # SETARRAYITEM_GC operations. - # - # - Remove "unsupported" uses of ConstPtrs away from the assembler. - # The backend must support at least 'p = SAME_AS(ConstPtr(..))' - # and might support more operations, like GETFIELD_GC. It should - # set GC_SUPPORTED_CONSTPTR to a dict of supported opnums. - # Or, as in the x86 backend, it can directly support all usages of - # ConstPtr and not need any rewrite at all (and then it should - # set GC_SUPPORTED_CONSTPTR to True). - # + # Add COND_CALLs to the write barrier before SETFIELD_GC and + # SETARRAYITEM_GC operations. newops = [] for op in operations: if op.opnum == rop.DEBUG_MERGE_POINT: continue - # ---------- replace ConstPtrs with SAME_AS ---------- - if (cpu.GC_SUPPORTED_CONSTPTR is not True and - op.opnum not in cpu.GC_SUPPORTED_CONSTPTR): - for i in range(len(op.args)): - v = op.args[i] - if isinstance(v, ConstPtr) and bool(v.value): - box = BoxPtr(v.value) - newops.append(ResOperation(rop.SAME_AS, [v], box)) - op.args[i] = box # ---------- write barrier for SETFIELD_GC ---------- if op.opnum == rop.SETFIELD_GC: v = op.args[1] Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py Mon Mar 8 16:43:50 2010 @@ -58,7 +58,7 @@ S = lltype.GcStruct('S') p0 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) p1 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)) - p = lltype.malloc(GcRefHandler.CONSTGCREF_ARRAY, 3) + p = lltype.malloc(GcRefHandler.CONSTGCREF_ARRAY, 4, zero=True) # ARRAY_SIGNED = lltype.Array(lltype.Signed) test = lltype.malloc(ARRAY_SIGNED, 5, immortal=True) @@ -69,11 +69,11 @@ p[0].gcref = p0 p[0].addr = (llmemory.cast_ptr_to_adr(test) + llmemory.itemoffsetof(ARRAY_SIGNED, 2)) - p[1].gcref = p0 - p[1].addr = (llmemory.cast_ptr_to_adr(test) + - llmemory.itemoffsetof(ARRAY_SIGNED, 4)) - p[2].gcref = p1 + p[2].gcref = p0 p[2].addr = (llmemory.cast_ptr_to_adr(test) + + llmemory.itemoffsetof(ARRAY_SIGNED, 4)) + p[3].gcref = p1 + p[3].addr = (llmemory.cast_ptr_to_adr(test) + llmemory.itemoffsetof(ARRAY_SIGNED, 3)) # gcrefhandler.start_tracing_varsized_part(llmemory.cast_ptr_to_adr(p), 42) @@ -297,59 +297,6 @@ gc_ll_descr.rewrite_assembler(None, operations) assert len(operations) == 0 - def test_rewrite_assembler_1(self): - # check rewriting of ConstPtrs - class MyFakeCPU: - GC_SUPPORTED_CONSTPTR = {rop.SAME_AS: None, - rop.OOISNOT: None} - S = lltype.GcStruct('S') - s = lltype.malloc(S) - s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - s2 = lltype.malloc(S) - s_gcref2 = lltype.cast_opaque_ptr(llmemory.GCREF, s2) - v_random_box = BoxPtr() - v_result = BoxInt() - v_result2 = BoxInt() - operations = [ - ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)], - v_result), - ResOperation(rop.OOISNOT, [v_random_box, ConstPtr(s_gcref2)], - v_result2), - ] - gc_ll_descr = self.gc_ll_descr - gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) - assert len(operations) == 3 - assert operations[0].opnum == rop.SAME_AS - assert operations[0].args == [ConstPtr(s_gcref)] - v_box = operations[0].result - assert isinstance(v_box, BoxPtr) - assert operations[1].opnum == rop.OOIS - assert operations[1].args == [v_random_box, v_box] - assert operations[1].result == v_result - assert operations[2].opnum == rop.OOISNOT - assert operations[2].args == [v_random_box, ConstPtr(s_gcref2)] - assert operations[2].result == v_result2 - - def test_rewrite_assembler_1_all_supported(self): - # check no rewriting of ConstPtrs if the cpu supports it fully - class MyFakeCPU: - GC_SUPPORTED_CONSTPTR = True - S = lltype.GcStruct('S') - s = lltype.malloc(S) - s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) - v_random_box = BoxPtr() - v_result = BoxInt() - operations = [ - ResOperation(rop.OOIS, [v_random_box, ConstPtr(s_gcref)], - v_result), - ] - gc_ll_descr = self.gc_ll_descr - gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations) - assert len(operations) == 1 - assert operations[0].opnum == rop.OOIS - assert operations[0].args == [v_random_box, ConstPtr(s_gcref)] - assert operations[0].result == v_result - def test_rewrite_assembler_2(self): # check write barriers before SETFIELD_GC v_base = BoxPtr() From arigo at codespeak.net Mon Mar 8 17:10:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 17:10:58 +0100 (CET) Subject: [pypy-svn] r71891 - in pypy/release/1.2.x: lib-python/modified-2.5.2/ctypes pypy/module/mmap pypy/objspace/flow pypy/objspace/flow/test pypy/rlib pypy/rpython/lltypesystem/module pypy/rpython/lltypesystem/module/test pypy/translator/c/test Message-ID: <20100308161058.DDAEC51054@codespeak.net> Author: arigo Date: Mon Mar 8 17:10:56 2010 New Revision: 71891 Modified: pypy/release/1.2.x/lib-python/modified-2.5.2/ctypes/__init__.py pypy/release/1.2.x/pypy/module/mmap/interp_mmap.py pypy/release/1.2.x/pypy/objspace/flow/objspace.py pypy/release/1.2.x/pypy/objspace/flow/test/test_objspace.py pypy/release/1.2.x/pypy/rlib/runicode.py pypy/release/1.2.x/pypy/rpython/lltypesystem/module/ll_math.py pypy/release/1.2.x/pypy/rpython/lltypesystem/module/test/test_ll_math.py pypy/release/1.2.x/pypy/translator/c/test/test_typed.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71802:71824 Modified: pypy/release/1.2.x/lib-python/modified-2.5.2/ctypes/__init__.py ============================================================================== --- pypy/release/1.2.x/lib-python/modified-2.5.2/ctypes/__init__.py (original) +++ pypy/release/1.2.x/lib-python/modified-2.5.2/ctypes/__init__.py Mon Mar 8 17:10:56 2010 @@ -23,21 +23,23 @@ from _ctypes import FormatError DEFAULT_MODE = RTLD_LOCAL -if _os.name == "posix" and _sys.platform == "darwin": - import gestalt +## --- the following is skipped because we don't have 'gestalt' so far, +## --- but we know pypy doesn't compile on Mac OS/X 10.3. +##if _os.name == "posix" and _sys.platform == "darwin": +## import gestalt + +## # gestalt.gestalt("sysv") returns the version number of the +## # currently active system file as BCD. +## # On OS X 10.4.6 -> 0x1046 +## # On OS X 10.2.8 -> 0x1028 +## # See also http://www.rgaros.nl/gestalt/ +## # +## # On OS X 10.3, we use RTLD_GLOBAL as default mode +## # because RTLD_LOCAL does not work at least on some +## # libraries. - # gestalt.gestalt("sysv") returns the version number of the - # currently active system file as BCD. - # On OS X 10.4.6 -> 0x1046 - # On OS X 10.2.8 -> 0x1028 - # See also http://www.rgaros.nl/gestalt/ - # - # On OS X 10.3, we use RTLD_GLOBAL as default mode - # because RTLD_LOCAL does not work at least on some - # libraries. - - if gestalt.gestalt("sysv") < 0x1040: - DEFAULT_MODE = RTLD_GLOBAL +## if gestalt.gestalt("sysv") < 0x1040: +## DEFAULT_MODE = RTLD_GLOBAL from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI Modified: pypy/release/1.2.x/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/release/1.2.x/pypy/module/mmap/interp_mmap.py (original) +++ pypy/release/1.2.x/pypy/module/mmap/interp_mmap.py Mon Mar 8 17:10:56 2010 @@ -54,7 +54,10 @@ tell.unwrap_spec = ['self'] def descr_size(self): - return self.space.wrap(self.mmap.file_size()) + try: + return self.space.wrap(self.mmap.file_size()) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') descr_size.unwrap_spec = ['self'] def write(self, data): @@ -83,6 +86,8 @@ except RValueError, v: raise OperationError(self.space.w_ValueError, self.space.wrap(v.message)) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') flush.unwrap_spec = ['self', int, int] def move(self, dest, src, count): @@ -96,7 +101,10 @@ def resize(self, newsize): self.check_valid() self.check_resizeable() - self.mmap.resize(newsize) + try: + self.mmap.resize(newsize) + except OSError, e: + raise wrap_oserror(self.space, e, 'w_EnvironmentError') resize.unwrap_spec = ['self', int] def __len__(self): Modified: pypy/release/1.2.x/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/release/1.2.x/pypy/objspace/flow/objspace.py (original) +++ pypy/release/1.2.x/pypy/objspace/flow/objspace.py Mon Mar 8 17:10:56 2010 @@ -370,6 +370,9 @@ def call_args(self, w_callable, args): try: fn = self.unwrap(w_callable) + if hasattr(fn, "_flowspace_rewrite_directly_as_"): + fn = fn._flowspace_rewrite_directly_as_ + w_callable = self.wrap(fn) sc = self.specialcases[fn] # TypeError if 'fn' not hashable except (UnwrapException, KeyError, TypeError): pass Modified: pypy/release/1.2.x/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/release/1.2.x/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/release/1.2.x/pypy/objspace/flow/test/test_objspace.py Mon Mar 8 17:10:56 2010 @@ -892,6 +892,22 @@ raise TypeError() py.test.raises(Exception, self.codetest, f) + def test__flowspace_rewrite_directly_as_(self): + def g(x): + pass + def f(x): + pass + f._flowspace_rewrite_directly_as_ = g + def h(x): + f(x) + graph = self.codetest(h) + assert self.all_operations(graph) == {'simple_call': 1} + for block in graph.iterblocks(): + if block.operations: + op = block.operations[0] + assert op.opname == 'simple_call' + assert op.args[0] == Constant(g) + class TestFlowObjSpaceDelay(Base): def setup_class(cls): Modified: pypy/release/1.2.x/pypy/rlib/runicode.py ============================================================================== --- pypy/release/1.2.x/pypy/rlib/runicode.py (original) +++ pypy/release/1.2.x/pypy/rlib/runicode.py Mon Mar 8 17:10:56 2010 @@ -16,26 +16,28 @@ # when sizeof(wchar_t) == 4. # Note that Python3 uses a similar implementation. def UNICHR(c): - if we_are_translated(): + assert not we_are_translated() + if c < sys.maxunicode or c > MAXUNICODE: return unichr(c) else: - if c < sys.maxunicode or c > MAXUNICODE: - return unichr(c) - else: - c -= 0x10000 - return (unichr(0xD800 + (c >> 10)) + - unichr(0xDC00 + (c & 0x03FF))) + c -= 0x10000 + return (unichr(0xD800 + (c >> 10)) + + unichr(0xDC00 + (c & 0x03FF))) + UNICHR._flowspace_rewrite_directly_as_ = unichr + # ^^^ NB.: for translation, it's essential to use this hack instead + # of calling unichr() from UNICHR(), because unichr() detects if there + # is a "try:except ValueError" immediately around it. def ORD(u): - if we_are_translated(): - return ord(u) - else: - if isinstance(u, unicode) and len(u) == 2: - ch1 = ord(u[0]) - ch2 = ord(u[1]) - if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: - return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 - return ord(u) + assert not we_are_translated() + if isinstance(u, unicode) and len(u) == 2: + ch1 = ord(u[0]) + ch2 = ord(u[1]) + if 0xD800 <= ch1 <= 0xDBFF and 0xDC00 <= ch2 <= 0xDFFF: + return (((ch1 - 0xD800) << 10) | (ch2 - 0xDC00)) + 0x10000 + return ord(u) + ORD._flowspace_rewrite_directly_as_ = ord + else: UNICHR = unichr ORD = ord Modified: pypy/release/1.2.x/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/release/1.2.x/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/release/1.2.x/pypy/rpython/lltypesystem/module/ll_math.py Mon Mar 8 17:10:56 2010 @@ -7,6 +7,7 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.rlib.rarithmetic import isinf math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE, sandboxsafe=True) @@ -26,16 +27,24 @@ def ll_math_frexp(x): exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - mantissa = math_frexp(x, exp_p) - exponent = rffi.cast(lltype.Signed, exp_p[0]) - lltype.free(exp_p, flavor='raw') + try: + _error_reset() + mantissa = math_frexp(x, exp_p) + _check_error(mantissa) + exponent = rffi.cast(lltype.Signed, exp_p[0]) + finally: + lltype.free(exp_p, flavor='raw') return (mantissa, exponent) def ll_math_modf(x): intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw') - fracpart = math_modf(x, intpart_p) - intpart = intpart_p[0] - lltype.free(intpart_p, flavor='raw') + try: + _error_reset() + fracpart = math_modf(x, intpart_p) + _check_error(fracpart) + intpart = intpart_p[0] + finally: + lltype.free(intpart_p, flavor='raw') return (fracpart, intpart) def ll_math_ldexp(x, exp): @@ -50,6 +59,8 @@ ERANGE = errno.ERANGE def _check_error(x): errno = rposix.get_errno() + if isinf(x): + errno = ERANGE if errno: if errno == ERANGE: if not x: Modified: pypy/release/1.2.x/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/release/1.2.x/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/release/1.2.x/pypy/rpython/lltypesystem/module/test/test_ll_math.py Mon Mar 8 17:10:56 2010 @@ -45,3 +45,26 @@ # underflows give 0.0 with no exception raised assert f(1.0, -10000) == 0.0 # sanity-check the host Python assert self.interpret(f, [1.0, -10000]) == 0.0 + + def test_overflow_1(self): + # this (probably, depending on platform) tests the case + # where the C function pow() sets ERANGE. + def f(x, y): + try: + return math.pow(x, y) + except OverflowError: + return -42.0 + + assert self.interpret(f, [10.0, 40000.0]) == -42.0 + + def test_overflow_2(self): + # this (not on Linux but on Mac OS/X at least) tests the case + # where the C function ldexp() does not set ERANGE, but + # returns +infinity. + def f(x, y): + try: + return math.ldexp(x, y) + except OverflowError: + return -42.0 + + assert self.interpret(f, [10.0, 40000]) == -42.0 Modified: pypy/release/1.2.x/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/c/test/test_typed.py (original) +++ pypy/release/1.2.x/pypy/translator/c/test/test_typed.py Mon Mar 8 17:10:56 2010 @@ -212,6 +212,18 @@ assert fn(-12) == -42 assert fn(sys.maxint) == -42 + def test_UNICHR(self): + from pypy.rlib.runicode import UNICHR + def f(x): + try: + return ord(UNICHR(x)) + except ValueError: + return -42 + fn = self.getcompiled(f, [int]) + assert fn(65) == 65 + assert fn(-12) == -42 + assert fn(sys.maxint) == -42 + def test_list_indexerror(self): def f(i): lst = [123, 456] From arigo at codespeak.net Mon Mar 8 17:12:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 17:12:05 +0100 (CET) Subject: [pypy-svn] r71892 - in pypy/release/1.2.x: ctypes_configure ctypes_configure/test pypy/lib pypy/lib/app_test pypy/lib/ctypes_config_cache pypy/lib/ctypes_config_cache/test pypy/module/imp pypy/module/imp/test pypy/translator/goal pypy/translator/sandbox pypy/translator/sandbox/test Message-ID: <20100308161205.8CCB451054@codespeak.net> Author: arigo Date: Mon Mar 8 17:12:03 2010 New Revision: 71892 Added: pypy/release/1.2.x/ctypes_configure/dumpcache.py - copied unchanged from r71873, pypy/trunk/ctypes_configure/dumpcache.py pypy/release/1.2.x/ctypes_configure/test/test_dumpcache.py - copied unchanged from r71873, pypy/trunk/ctypes_configure/test/test_dumpcache.py pypy/release/1.2.x/pypy/lib/app_test/test_syslog.py - copied unchanged from r71873, pypy/trunk/pypy/lib/app_test/test_syslog.py pypy/release/1.2.x/pypy/lib/ctypes_config_cache/ (props changed) - copied from r71873, pypy/trunk/pypy/lib/ctypes_config_cache/ Removed: pypy/release/1.2.x/pypy/lib/ctypes_configure Modified: pypy/release/1.2.x/ctypes_configure/cbuild.py pypy/release/1.2.x/ctypes_configure/configure.py pypy/release/1.2.x/pypy/lib/_hashlib.py pypy/release/1.2.x/pypy/lib/_locale.py pypy/release/1.2.x/pypy/lib/app_test/test_hashlib.py pypy/release/1.2.x/pypy/lib/app_test/test_locale.py pypy/release/1.2.x/pypy/lib/app_test/test_pyexpat.py pypy/release/1.2.x/pypy/lib/app_test/test_resource.py pypy/release/1.2.x/pypy/lib/ctypes_config_cache/test/ (props changed) pypy/release/1.2.x/pypy/lib/pyexpat.py pypy/release/1.2.x/pypy/lib/resource.py pypy/release/1.2.x/pypy/lib/syslog.py pypy/release/1.2.x/pypy/module/imp/importing.py pypy/release/1.2.x/pypy/module/imp/test/test_import.py pypy/release/1.2.x/pypy/translator/goal/targetpypystandalone.py pypy/release/1.2.x/pypy/translator/sandbox/pypy_interact.py pypy/release/1.2.x/pypy/translator/sandbox/test/test_pypy_interact.py pypy/release/1.2.x/pypy/translator/sandbox/test/test_vfs.py pypy/release/1.2.x/pypy/translator/sandbox/vfs.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71868:71873 Modified: pypy/release/1.2.x/ctypes_configure/cbuild.py ============================================================================== --- pypy/release/1.2.x/ctypes_configure/cbuild.py (original) +++ pypy/release/1.2.x/ctypes_configure/cbuild.py Mon Mar 8 17:12:03 2010 @@ -5,7 +5,7 @@ debug = 0 -configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure') +configdir = py.path.local.make_numbered_dir(prefix='ctypes_configure-') class ExternalCompilationInfo(object): Modified: pypy/release/1.2.x/ctypes_configure/configure.py ============================================================================== --- pypy/release/1.2.x/ctypes_configure/configure.py (original) +++ pypy/release/1.2.x/ctypes_configure/configure.py Mon Mar 8 17:12:03 2010 @@ -164,7 +164,7 @@ for key in dir(CConfig): value = getattr(CConfig, key) if isinstance(value, CConfigEntry): - entries.append((key, value)) + entries.append((key, value)) if entries: # can be empty if there are only CConfigSingleEntries writer = _CWriter(CConfig) @@ -201,7 +201,6 @@ writer = _CWriter(CConfig) writer.write_header() res[key] = value.question(writer.ask_gcc) - return res # ____________________________________________________________ @@ -210,7 +209,6 @@ class CConfigEntry(object): "Abstract base class." - class Struct(CConfigEntry): """An entry in a CConfig class that stands for an externally defined structure. @@ -313,7 +311,6 @@ S.__name__ = name return S - class SimpleType(CConfigEntry): """An entry in a CConfig class that stands for an externally defined simple numeric type. @@ -350,7 +347,6 @@ ctype = fixup_ctype(ctype, self.name, (size, sign)) return ctype - class ConstantInteger(CConfigEntry): """An entry in a CConfig class that stands for an externally defined integer constant. Modified: pypy/release/1.2.x/pypy/lib/_hashlib.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/_hashlib.py (original) +++ pypy/release/1.2.x/pypy/lib/_hashlib.py Mon Mar 8 17:12:03 2010 @@ -1,6 +1,8 @@ from ctypes import * import ctypes.util -from ctypes_configure import configure + +# load the platform-specific cache made by running hashlib.ctc.py +from ctypes_config_cache._hashlib_cache import * # Note: OpenSSL on OS X only provides md5 and sha1 libpath = ctypes.util.find_library('ssl') @@ -16,18 +18,6 @@ else: return buffer(x)[:] -class CConfig: - _compilation_info_ = configure.ExternalCompilationInfo( - includes=['openssl/evp.h'], - ) - EVP_MD = configure.Struct('EVP_MD', - []) - EVP_MD_CTX = configure.Struct('EVP_MD_CTX', - [('digest', c_void_p)]) -c = configure.configure(CConfig) -EVP_MD_CTX = c['EVP_MD_CTX'] -EVP_MD = c['EVP_MD'] - def patch_fields(fields): res = [] for k, v in fields: @@ -39,7 +29,6 @@ class EVP_MD_CTX(Structure): _fields_ = patch_fields(EVP_MD_CTX._fields_) -del c # OpenSSL initialization lib.OpenSSL_add_all_digests() Modified: pypy/release/1.2.x/pypy/lib/_locale.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/_locale.py (original) +++ pypy/release/1.2.x/pypy/lib/_locale.py Mon Mar 8 17:12:03 2010 @@ -7,48 +7,16 @@ c_ubyte, c_int, c_char_p, c_wchar_p) from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno -from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + +# load the platform-specific cache made by running locale.ctc.py +from ctypes_config_cache._locale_cache import * + size_t = c_int # XXX check where this comes from CHAR_MAX = 127 -_CONSTANTS = ( - 'LC_CTYPE', - 'LC_NUMERIC', - 'LC_TIME', - 'LC_COLLATE', - 'LC_MONETARY', - 'LC_MESSAGES', - 'LC_ALL', - 'LC_PAPER', - 'LC_NAME', - 'LC_ADDRESS', - 'LC_TELEPHONE', - 'LC_MEASUREMENT', - 'LC_IDENTIFICATION', -) - -class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) -for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) - -try: - locale_config = configure(LocaleConfigure, noerr=True) -except Exception, e: - # should probably be moved into configure() - # as an optional feature - raise ImportError("%s: %s" % (e.__class__, e)) - -for key in _CONSTANTS: - globals()[key] = locale_config[key] -del LocaleConfigure -del locale_config - -HAS_LANGINFO = True # Ubuntu Gusty i386 structure class lconv(Structure): @@ -288,29 +256,6 @@ raise NotImplementedError() if HAS_LANGINFO: - # this is incomplete list - langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' - 'YESEXPR NOEXPR CRNCYSTR').split(" ") - for i in range(1, 8): - langinfo_names.append("DAY_%d" % i) - langinfo_names.append("ABDAY_%d" % i) - for i in range(1, 13): - langinfo_names.append("MON_%d" % i) - langinfo_names.append("ABMON_%d" % i) - - class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) - nl_item = SimpleType('nl_item') - for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) - - config = configure(LanginfoConfigure) - nl_item = config['nl_item'] - for key in langinfo_names: - globals()[key] = config[key] - del LanginfoConfigure - del config - _nl_langinfo = libc.nl_langinfo _nl_langinfo.argtypes = (nl_item,) _nl_langinfo.restype = c_char_p @@ -369,9 +314,8 @@ 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', 'bindtextdomain', 'CHAR_MAX', -) + _CONSTANTS + tuple(langinfo_names) +) + ALL_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: __all__ += ('nl_langinfo',) - Modified: pypy/release/1.2.x/pypy/lib/app_test/test_hashlib.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/app_test/test_hashlib.py (original) +++ pypy/release/1.2.x/pypy/lib/app_test/test_hashlib.py Mon Mar 8 17:12:03 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('hashlib.ctc.py') + from pypy.lib import hashlib, _hashlib def test_unicode(): Modified: pypy/release/1.2.x/pypy/lib/app_test/test_locale.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/app_test/test_locale.py (original) +++ pypy/release/1.2.x/pypy/lib/app_test/test_locale.py Mon Mar 8 17:12:03 2010 @@ -1,14 +1,19 @@ import py -import locale import sys +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('locale.ctc.py') + +from pypy.lib import _locale + + def setup_module(mod): if sys.platform == 'darwin': py.test.skip("Locale support on MacOSX is minimal and cannot be tested") class TestLocale: def setup_class(cls): - cls.oldlocale = locale.setlocale(locale.LC_NUMERIC) + cls.oldlocale = _locale.setlocale(_locale.LC_NUMERIC) if sys.platform.startswith("win"): cls.tloc = "en" elif sys.platform.startswith("freebsd"): @@ -16,14 +21,15 @@ else: cls.tloc = "en_US.UTF8" try: - locale.setlocale(locale.LC_NUMERIC, cls.tloc) - except locale.Error: + _locale.setlocale(_locale.LC_NUMERIC, cls.tloc) + except _locale.Error: py.test.skip("test locale %s not supported" % cls.tloc) def teardown_class(cls): - locale.setlocale(locale.LC_NUMERIC, cls.oldlocale) + _locale.setlocale(_locale.LC_NUMERIC, cls.oldlocale) def test_format(self): + py.test.skip("XXX fix or kill me") def testformat(formatstr, value, grouping = 0, output=None): if output: @@ -41,8 +47,11 @@ testformat("%20.f", -42, grouping=1, output=' -42') testformat("%+10.f", -4200, grouping=1, output=' -4,200') testformat("%-10.f", 4200, grouping=1, output='4,200 ') - # Invoke getpreferredencoding to make sure it does not cause exceptions, - locale.getpreferredencoding() + + def test_getpreferredencoding(self): + py.test.skip("XXX fix or kill me") + # Invoke getpreferredencoding to make sure it does not cause exceptions + _locale.getpreferredencoding() # Test BSD Rune locale's bug for isctype functions. def test_bsd_bug(self): @@ -51,8 +60,8 @@ result = getattr(s, method)() assert result == output - oldlocale = locale.setlocale(locale.LC_CTYPE) - locale.setlocale(locale.LC_CTYPE, self.tloc) + oldlocale = _locale.setlocale(_locale.LC_CTYPE) + _locale.setlocale(_locale.LC_CTYPE, self.tloc) try: teststrop('\x20', 'isspace', True) teststrop('\xa0', 'isspace', False) @@ -66,4 +75,4 @@ teststrop('\xcc\x85', 'lower', '\xcc\x85') teststrop('\xed\x95\xa0', 'upper', '\xed\x95\xa0') finally: - locale.setlocale(locale.LC_CTYPE, oldlocale) + _locale.setlocale(_locale.LC_CTYPE, oldlocale) Modified: pypy/release/1.2.x/pypy/lib/app_test/test_pyexpat.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/app_test/test_pyexpat.py (original) +++ pypy/release/1.2.x/pypy/lib/app_test/test_pyexpat.py Mon Mar 8 17:12:03 2010 @@ -4,6 +4,9 @@ import StringIO, sys import unittest, py +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('pyexpat.ctc.py') + from pypy.lib import pyexpat #from xml.parsers import expat expat = pyexpat Modified: pypy/release/1.2.x/pypy/lib/app_test/test_resource.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/app_test/test_resource.py (original) +++ pypy/release/1.2.x/pypy/lib/app_test/test_resource.py Mon Mar 8 17:12:03 2010 @@ -1,3 +1,6 @@ +from pypy.lib.ctypes_config_cache import rebuild +rebuild.rebuild_one('resource.ctc.py') + from pypy.lib import resource def test_resource(): Modified: pypy/release/1.2.x/pypy/lib/pyexpat.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/pyexpat.py (original) +++ pypy/release/1.2.x/pypy/lib/pyexpat.py Mon Mar 8 17:12:03 2010 @@ -1,46 +1,15 @@ import ctypes import ctypes.util -from ctypes_configure import configure from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p import sys +# load the platform-specific cache made by running pyexpat.ctc.py +from ctypes_config_cache._pyexpat_cache import * + + lib = ctypes.CDLL(ctypes.util.find_library('expat')) -class CConfigure: - _compilation_info_ = configure.ExternalCompilationInfo( - includes = ['expat.h'], - libraries = ['expat'], - pre_include_lines = [ - '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'], - ) - - XML_Char = configure.SimpleType('XML_Char', ctypes.c_char) - XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION') - for name in ['XML_PARAM_ENTITY_PARSING_NEVER', - 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE', - 'XML_PARAM_ENTITY_PARSING_ALWAYS']: - locals()[name] = configure.ConstantInteger(name) - - XML_Encoding = configure.Struct('XML_Encoding',[ - ('data', c_void_p), - ('convert', c_void_p), - ('release', c_void_p), - ('map', c_int * 256)]) - XML_Content = configure.Struct('XML_Content',[ - ('numchildren', c_int), - ('children', c_void_p), - ('name', c_char_p), - ('type', c_int), - ('quant', c_int), - ]) - # this is insanely stupid - XML_FALSE = configure.ConstantInteger('XML_FALSE') - XML_TRUE = configure.ConstantInteger('XML_TRUE') - -info = configure.configure(CConfigure) -for k, v in info.items(): - globals()[k] = v XML_Content.children = POINTER(XML_Content) XML_Parser = ctypes.c_void_p # an opaque pointer Modified: pypy/release/1.2.x/pypy/lib/resource.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/resource.py (original) +++ pypy/release/1.2.x/pypy/lib/resource.py Mon Mar 8 17:12:03 2010 @@ -2,45 +2,18 @@ if sys.platform == 'win32': raise ImportError('resource module not available for win32') +# load the platform-specific cache made by running resource.ctc.py +from ctypes_config_cache._resource_cache import * + from ctypes_support import standard_c_lib as libc from ctypes_support import get_errno from ctypes import Structure, c_int, c_long, byref, sizeof from errno import EINVAL, EPERM -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger, - SimpleType) import _structseq class error(Exception): pass -_CONSTANTS = ( - 'RLIM_INFINITY', - 'RLIM_NLIMITS', -) -_OPTIONAL_CONSTANTS = ( - 'RLIMIT_CPU', - 'RLIMIT_FSIZE', - 'RLIMIT_DATA', - 'RLIMIT_STACK', - 'RLIMIT_CORE', - 'RLIMIT_RSS', - 'RLIMIT_NPROC', - 'RLIMIT_NOFILE', - 'RLIMIT_OFILE', - 'RLIMIT_MEMLOCK', - 'RLIMIT_AS', - 'RLIMIT_LOCKS', - 'RLIMIT_SIGPENDING', - 'RLIMIT_MSGQUEUE', - 'RLIMIT_NICE', - 'RLIMIT_RTPRIO', - 'RLIMIT_VMEM', - - 'RUSAGE_BOTH', - 'RUSAGE_SELF', - 'RUSAGE_CHILDREN', -) # Read required libc functions _getrusage = libc.getrusage @@ -52,27 +25,6 @@ from os import sysconf _getpagesize = None -# Setup our configure -class ResourceConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/resource.h']) - rlim_t = SimpleType('rlim_t') -for key in _CONSTANTS: - setattr(ResourceConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(ResourceConfigure, key, DefinedConstantInteger(key)) - -# Configure constants and types -config = configure(ResourceConfigure) -rlim_t = config['rlim_t'] -sizeof_rlim_t = 1<<(sizeof(rlim_t) * 8) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -del config class timeval(Structure): _fields_ = ( @@ -126,9 +78,9 @@ ru_nivcsw = _structseq.structseqfield(15) def rlimit_check_bounds(rlim_cur, rlim_max): - if rlim_cur > sizeof_rlim_t: + if rlim_cur > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_cur) - if rlim_max > sizeof_rlim_t: + if rlim_max > rlim_t_max: raise ValueError("%d does not fit into rlim_t" % rlim_max) class rlimit(Structure): @@ -202,10 +154,9 @@ # Irix 5.3 has _SC_PAGESIZE, but not _SC_PAGE_SIZE return sysconf("SC_PAGESIZE") -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'error', 'timeval', 'struct_rusage', 'rlimit', 'getrusage', 'getrlimit', 'setrlimit', 'getpagesize', ) -del optional_constants - +del ALL_CONSTANTS Modified: pypy/release/1.2.x/pypy/lib/syslog.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/syslog.py (original) +++ pypy/release/1.2.x/pypy/lib/syslog.py Mon Mar 8 17:12:03 2010 @@ -9,79 +9,11 @@ if sys.platform == 'win32': raise ImportError("No syslog on Windows") +# load the platform-specific cache made by running syslog.ctc.py +from ctypes_config_cache._syslog_cache import * + from ctypes_support import standard_c_lib as libc from ctypes import c_int, c_char_p -from ctypes_configure.configure import (configure, - ExternalCompilationInfo, ConstantInteger, DefinedConstantInteger) - -_CONSTANTS = ( - 'LOG_EMERG', - 'LOG_ALERT', - 'LOG_CRIT', - 'LOG_ERR', - 'LOG_WARNING', - 'LOG_NOTICE', - 'LOG_INFO', - 'LOG_DEBUG', - - 'LOG_PID', - 'LOG_CONS', - 'LOG_NDELAY', - - 'LOG_KERN', - 'LOG_USER', - 'LOG_MAIL', - 'LOG_DAEMON', - 'LOG_AUTH', - 'LOG_LPR', - 'LOG_LOCAL0', - 'LOG_LOCAL1', - 'LOG_LOCAL2', - 'LOG_LOCAL3', - 'LOG_LOCAL4', - 'LOG_LOCAL5', - 'LOG_LOCAL6', - 'LOG_LOCAL7', -) -_OPTIONAL_CONSTANTS = ( - 'LOG_NOWAIT', - 'LOG_PERROR', - - 'LOG_SYSLOG', - 'LOG_CRON', - 'LOG_UUCP', - 'LOG_NEWS', -) - -# Constant aliases if there are not defined -_ALIAS = ( - ('LOG_SYSLOG', 'LOG_DAEMON'), - ('LOG_CRON', 'LOG_DAEMON'), - ('LOG_NEWS', 'LOG_MAIL'), - ('LOG_UUCP', 'LOG_MAIL'), -) - -class SyslogConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['sys/syslog.h']) -for key in _CONSTANTS: - setattr(SyslogConfigure, key, ConstantInteger(key)) -for key in _OPTIONAL_CONSTANTS: - setattr(SyslogConfigure, key, DefinedConstantInteger(key)) - -config = configure(SyslogConfigure) -for key in _CONSTANTS: - globals()[key] = config[key] -optional_constants = [] -for key in _OPTIONAL_CONSTANTS: - if config[key] is not None: - globals()[key] = config[key] - optional_constants.append(key) -for alias, key in _ALIAS: - if alias in optional_constants: - continue - globals()[alias] = globals()[key] - optional_constants.append(alias) -del config # Real prototype is: # void syslog(int priority, const char *format, ...); @@ -124,9 +56,8 @@ def LOG_UPTO(pri): return (1 << (pri + 1)) - 1 -__all__ = _CONSTANTS + tuple(optional_constants) + ( +__all__ = ALL_CONSTANTS + ( 'openlog', 'syslog', 'closelog', 'setlogmask', 'LOG_MASK', 'LOG_UPTO') -del optional_constants - +del ALL_CONSTANTS Modified: pypy/release/1.2.x/pypy/module/imp/importing.py ============================================================================== --- pypy/release/1.2.x/pypy/module/imp/importing.py (original) +++ pypy/release/1.2.x/pypy/module/imp/importing.py Mon Mar 8 17:12:03 2010 @@ -648,9 +648,9 @@ d = x & 0xff stream.write(chr(a) + chr(b) + chr(c) + chr(d)) -def check_compiled_module(space, pycfilename, expected_mtime=0): +def check_compiled_module(space, pycfilename, expected_mtime): """ - Check if a pyc file's magic number and (optionally) mtime match. + Check if a pyc file's magic number and mtime match. """ stream = None try: @@ -659,11 +659,10 @@ if magic != get_pyc_magic(space): stream.close() return None - if expected_mtime != 0: - pyc_mtime = _r_long(stream) - if pyc_mtime != expected_mtime: - stream.close() - return None + pyc_mtime = _r_long(stream) + if pyc_mtime != expected_mtime: + stream.close() + return None return stream except StreamErrors: if stream: Modified: pypy/release/1.2.x/pypy/module/imp/test/test_import.py ============================================================================== --- pypy/release/1.2.x/pypy/module/imp/test/test_import.py (original) +++ pypy/release/1.2.x/pypy/module/imp/test/test_import.py Mon Mar 8 17:12:03 2010 @@ -496,6 +496,12 @@ cpathname, mtime+1) assert ret is None + + # also check with expected mtime==0 (nothing special any more about 0) + ret = importing.check_compiled_module(space, + cpathname, + 0) + assert ret is None os.remove(cpathname) # check for wrong version Modified: pypy/release/1.2.x/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/release/1.2.x/pypy/translator/goal/targetpypystandalone.py Mon Mar 8 17:12:03 2010 @@ -186,6 +186,10 @@ #elif config.objspace.usemodules.clr: # config.translation.backend == "cli" + if config.translation.sandbox: + config.objspace.lonepycfiles = False + config.objspace.usepycfiles = False + config.objspace.nofaking = True config.objspace.compiler = "ast" config.translating = True @@ -216,6 +220,9 @@ return PyPyJitPolicy() def get_entry_point(self, config): + from pypy.lib.ctypes_config_cache import rebuild + rebuild.try_rebuild() + space = make_objspace(config) # manually imports app_main.py Modified: pypy/release/1.2.x/pypy/translator/sandbox/pypy_interact.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/sandbox/pypy_interact.py (original) +++ pypy/release/1.2.x/pypy/translator/sandbox/pypy_interact.py Mon Mar 8 17:12:03 2010 @@ -45,18 +45,21 @@ # * can access its own executable # * can access the pure Python libraries # * can access the temporary usession directory as /tmp + exclude = ['.pyc', '.pyo'] if self.tmpdir is None: tmpdirnode = Dir({}) else: - tmpdirnode = RealDir(self.tmpdir) + tmpdirnode = RealDir(self.tmpdir, exclude=exclude) pypydist = os.path.dirname(os.path.abspath(autopath.pypydir)) return Dir({ 'bin': Dir({ 'pypy-c': RealFile(self.executable), - 'lib-python': RealDir(os.path.join(pypydist, 'lib-python')), + 'lib-python': RealDir(os.path.join(pypydist, 'lib-python'), + exclude=exclude), 'pypy': Dir({ - 'lib': RealDir(os.path.join(pypydist, 'pypy', 'lib')), + 'lib': RealDir(os.path.join(pypydist, 'pypy', 'lib'), + exclude=exclude), }), }), 'tmp': tmpdirnode, Modified: pypy/release/1.2.x/pypy/translator/sandbox/test/test_pypy_interact.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/sandbox/test/test_pypy_interact.py (original) +++ pypy/release/1.2.x/pypy/translator/sandbox/test/test_pypy_interact.py Mon Mar 8 17:12:03 2010 @@ -36,6 +36,12 @@ assert_(False, "os.stat('site') should have failed") 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") + try: + os.stat('/bin/lib-python/modified-2.5.2/site.pyc') + except OSError: + pass + else: + assert_(False, "os.stat('....pyc') should have failed") fd = os.open('/bin/lib-python/modified-2.5.2/site.py', os.O_RDONLY, 0666) length = 8192 ofs = 0 Modified: pypy/release/1.2.x/pypy/translator/sandbox/test/test_vfs.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/sandbox/test/test_vfs.py (original) +++ pypy/release/1.2.x/pypy/translator/sandbox/test/test_vfs.py Mon Mar 8 17:12:03 2010 @@ -90,3 +90,19 @@ else: py.test.raises(OSError, v_test_vfs.join, '.hidden') py.test.raises(OSError, v_test_vfs.join, '.subdir2') + +def test_realdir_exclude(): + xdir = udir.ensure('test_realdir_exclude', dir=1) + xdir.ensure('test_realdir_exclude.yes') + xdir.ensure('test_realdir_exclude.no') + v_udir = RealDir(str(udir), exclude=['.no']) + v_xdir = v_udir.join('test_realdir_exclude') + assert 'test_realdir_exclude.yes' in v_xdir.keys() + assert 'test_realdir_exclude.no' not in v_xdir.keys() + v_xdir.join('test_realdir_exclude.yes') # works + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.no') + # Windows and Mac tests, for the case + py.test.raises(OSError, v_xdir.join, 'Test_RealDir_Exclude.no') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.No') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.nO') + py.test.raises(OSError, v_xdir.join, 'test_realdir_exclude.NO') Modified: pypy/release/1.2.x/pypy/translator/sandbox/vfs.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/sandbox/vfs.py (original) +++ pypy/release/1.2.x/pypy/translator/sandbox/vfs.py Mon Mar 8 17:12:03 2010 @@ -64,21 +64,30 @@ # with '.' simply don't exist. If follow_links=True, then symlinks are # transparently followed (they look like a regular file or directory to # the sandboxed process). If follow_links=False, the subprocess is - # not allowed to access them at all. - def __init__(self, path, show_dotfiles=False, follow_links=False): + # not allowed to access them at all. Finally, exclude is a list of + # file endings that we filter out (note that we also filter out files + # with the same ending but a different case, to be safe). + def __init__(self, path, show_dotfiles=False, follow_links=False, + exclude=[]): self.path = path self.show_dotfiles = show_dotfiles self.follow_links = follow_links + self.exclude = [excl.lower() for excl in exclude] def __repr__(self): return '' % (self.path,) def keys(self): names = os.listdir(self.path) if not self.show_dotfiles: names = [name for name in names if not name.startswith('.')] + for excl in self.exclude: + names = [name for name in names if not name.lower().endswith(excl)] return names def join(self, name): if name.startswith('.') and not self.show_dotfiles: raise OSError(errno.ENOENT, name) + for excl in self.exclude: + if name.lower().endswith(excl): + raise OSError(errno.ENOENT, name) path = os.path.join(self.path, name) if self.follow_links: st = os.stat(path) @@ -86,7 +95,8 @@ st = os.lstat(path) if stat.S_ISDIR(st.st_mode): return RealDir(path, show_dotfiles = self.show_dotfiles, - follow_links = self.follow_links) + follow_links = self.follow_links, + exclude = self.exclude) elif stat.S_ISREG(st.st_mode): return RealFile(path) else: From arigo at codespeak.net Mon Mar 8 18:27:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Mar 2010 18:27:53 +0100 (CET) Subject: [pypy-svn] r71898 - in pypy/branch/jit-constptr/pypy/jit/backend: llsupport llsupport/test x86 x86/test Message-ID: <20100308172753.EAE1C51054@codespeak.net> Author: arigo Date: Mon Mar 8 18:27:52 2010 New Revision: 71898 Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py pypy/branch/jit-constptr/pypy/jit/backend/x86/regalloc.py pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_gc_integration.py pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py Log: Intermediate stage. Random progress, but I still need to write tests and implement code that notes where in the assembler the convert_to_imm(ConstPtr(..)) results get written to. Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/gcframework.py Mon Mar 8 18:27:52 2010 @@ -48,24 +48,22 @@ def __init__(self, layoutbuilder): self.constgcref_array_type_id = layoutbuilder.get_type_id( self.CONSTGCREF_ARRAY) - self.full_constgcref_array_type_id = llop.combine_ushort( - lltype.Signed, - self.constgcref_array_type_id, - 0) def _freeze_(self): return True def start_tracing_varsized_part(self, obj, typeid): """Called by the GC just before tracing the object 'obj'.""" - fulltypeid = llop.combine_ushort(lltype.Signed, typeid, 0) - if fulltypeid == self.full_constgcref_array_type_id: + fulltypeid = rffi.cast(lltype.Signed, typeid) + reftypeid = rffi.cast(lltype.Signed, self.constgcref_array_type_id) + if fulltypeid == reftypeid: self.do_start_stop_tracing(obj, False) def stop_tracing_varsized_part(self, obj, typeid): """Called by the GC just after tracing the object 'obj'.""" - fulltypeid = llop.combine_ushort(lltype.Signed, typeid, 0) - if fulltypeid == self.full_constgcref_array_type_id: + fulltypeid = rffi.cast(lltype.Signed, typeid) + reftypeid = rffi.cast(lltype.Signed, self.constgcref_array_type_id) + if fulltypeid == reftypeid: self.do_start_stop_tracing(obj, True) def do_start_stop_tracing(self, obj, done): Modified: pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/llsupport/test/test_gc.py Mon Mar 8 18:27:52 2010 @@ -186,7 +186,7 @@ class FakeTranslator: config = config_ class FakeCPU: - GC_SUPPORTED_CONSTPTR = {rop.SAME_AS: None} + pass gcdescr = get_description(config_) translator = FakeTranslator() llop1 = FakeLLOp() Modified: pypy/branch/jit-constptr/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/x86/regalloc.py Mon Mar 8 18:27:52 2010 @@ -41,7 +41,7 @@ if isinstance(c, ConstInt): return imm(c.value) elif isinstance(c, ConstPtr): - if we_are_translated() and c.value and rgc.can_move(c.value): + if we_are_translated() and c.value: print "convert_to_imm: ConstPtr needs special care" raise AssertionError return imm(rffi.cast(lltype.Signed, c.value)) Modified: pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_gc_integration.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_gc_integration.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_gc_integration.py Mon Mar 8 18:27:52 2010 @@ -15,7 +15,7 @@ from pypy.rpython.annlowlevel import llhelper from pypy.rpython.lltypesystem import rclass, rstr from pypy.jit.backend.x86.ri386 import * -from pypy.jit.backend.llsupport.gc import GcLLDescr_framework, GcRefList, GcPtrFieldDescr +from pypy.jit.backend.llsupport.gcframework import GcLLDescr_framework from pypy.jit.backend.x86.test.test_regalloc import MockAssembler from pypy.jit.backend.x86.test.test_regalloc import BaseTestRegalloc @@ -49,9 +49,7 @@ gcrootmap = MockGcRootMap() def initialize(self): - self.gcrefs = GcRefList() - self.gcrefs.initialize() - self.single_gcref_descr = GcPtrFieldDescr(0) + pass rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func Modified: pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/branch/jit-constptr/pypy/jit/backend/x86/test/test_zrpy_gc.py Mon Mar 8 18:27:52 2010 @@ -412,8 +412,29 @@ def test_compile_hybrid_external_exception_handling(self): self.run('compile_hybrid_external_exception_handling') - - def define_compile_hybrid_bug1(self): + + def define_compile_hybrid_movable_gcref(self): + @purefunction + def moving(): + return X(1) + + @dont_look_inside + def do_more_stuff(): + rgc.collect() + return X(5) + + def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s): + x0 = do_more_stuff() + check(moving().x == 1) + n -= 1 + return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s + + return None, f, None + + def test_compile_hybrid_movable_gcref(self): + self.run('compile_hybrid_movable_gcref', 200) + + def define_compile_hybrid_nonmovable_gcref(self): @purefunction def nonmoving(): x = X(1) @@ -436,8 +457,8 @@ return None, f, None - def test_compile_hybrid_bug1(self): - self.run('compile_hybrid_bug1', 200) + def test_compile_hybrid_nonmovable_gcref(self): + self.run('compile_hybrid_nonmovable_gcref', 200) def define_compile_hybrid_vref(self): from pypy.rlib.jit import virtual_ref, virtual_ref_finish From fijal at codespeak.net Mon Mar 8 21:02:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 21:02:00 +0100 (CET) Subject: [pypy-svn] r71911 - pypy/trunk/pypy/doc Message-ID: <20100308200200.20DDC282BD4@codespeak.net> Author: fijal Date: Mon Mar 8 21:01:49 2010 New Revision: 71911 Modified: pypy/trunk/pypy/doc/download.txt Log: Remove contents and replace with a link to download on pypy.org Modified: pypy/trunk/pypy/doc/download.txt ============================================================================== --- pypy/trunk/pypy/doc/download.txt (original) +++ pypy/trunk/pypy/doc/download.txt Mon Mar 8 21:01:49 2010 @@ -2,28 +2,6 @@ Download one of the following release files: ============================================= -PyPy 1.2 Sources: ------------------ +Download page has moved to `pypy.org`_. -* `pypy-1.2.0.tar.bz2`_ (sources, unix line endings) or -* `pypy-1.2.0.tar.gz`_ (sources, unix line endings) or -* `pypy-1.2.0.zip`_ (sources, windows line-endings) - -.. _`pypy-1.2.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.bz2 -.. _`pypy-1.2.0.zip`: http://codespeak.net/download/pypy/pypy-1.2.0.zip -.. _`pypy-1.2.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.gz - -Prebuilt binaries -~~~~~~~~~~~~~~~~~ - -XXX - -The ``lang`` repository -~~~~~~~~~~~~~~~~~~~~~~~ - -The ``lang`` part of our repository, which contains other interpreters -developped mostly as external contributions, has moved and is no longer -included in the above packages. You can grab it by `browsing the -Subversion source`__. - -.. __: http://codespeak.net/svn/pypy/lang/ +.. _`pypy.org`: http://pypy.org/download.html From fijal at codespeak.net Mon Mar 8 21:08:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 21:08:22 +0100 (CET) Subject: [pypy-svn] r71913 - pypy/trunk/pypy/tool Message-ID: <20100308200822.46AA0282BD8@codespeak.net> Author: fijal Date: Mon Mar 8 21:08:11 2010 New Revision: 71913 Removed: pypy/trunk/pypy/tool/makerelease.py Log: I believe that this script is so outdated that we don't want to upgrade it From fijal at codespeak.net Mon Mar 8 22:52:47 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 22:52:47 +0100 (CET) Subject: [pypy-svn] r71921 - in pypy/trunk/pypy/tool: . test Message-ID: <20100308215247.A8CCB282BD4@codespeak.net> Author: fijal Date: Mon Mar 8 22:52:46 2010 New Revision: 71921 Modified: pypy/trunk/pypy/tool/package.py pypy/trunk/pypy/tool/test/test_package.py Log: Improve a bit packaging tool Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Mon Mar 8 22:52:46 2010 @@ -37,7 +37,7 @@ if not pypy_c.check(): raise PyPyCNotFound('Please compile pypy first, using translate.py') builddir = udir.ensure("build", dir=True) - pypydir = builddir.ensure("pypy", dir=True) + pypydir = builddir.ensure(name, dir=True) shutil.copytree(str(basedir.join('lib-python')), str(pypydir.join('lib-python')), ignore=ignore_patterns('.svn')) @@ -50,8 +50,9 @@ old_dir = os.getcwd() try: os.chdir(str(builddir)) + os.system("strip " + str(builddir.join('bin', 'pypy-c'))) os.system('tar cvjf ' + str(builddir.join(name + '.tar.bz2')) + - " pypy") + " " + name) finally: os.chdir(old_dir) return builddir # for tests Modified: pypy/trunk/pypy/tool/test/test_package.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_package.py (original) +++ pypy/trunk/pypy/tool/test/test_package.py Mon Mar 8 22:52:46 2010 @@ -8,17 +8,17 @@ # make sure we have sort of pypy-c pypy_c = py.path.local(pypydir).join('translator', 'goal', 'pypy-c') if not pypy_c.check(): - pypy_c.write("xxx") + shutil.copy("/usr/bin/echo", pypy_c) fake_pypy_c = True else: fake_pypy_c = False try: builddir = main(py.path.local(pypydir).dirpath(), 'test') - assert builddir.join('pypy', 'lib-python', '2.5.2', 'test').check() - assert builddir.join('pypy', 'bin', 'pypy-c').check() - assert builddir.join('pypy', 'pypy', 'lib', 'syslog.py').check() + assert builddir.join('test', 'lib-python', '2.5.2', 'test').check() + assert builddir.join('test', 'bin', 'pypy-c').check() + assert builddir.join('test', 'pypy', 'lib', 'syslog.py').check() th = tarfile.open(str(builddir.join('test.tar.bz2'))) - assert th.getmember('pypy/pypy/lib/syslog.py') + assert th.getmember('test/pypy/lib/syslog.py') finally: if fake_pypy_c: pypy_c.remove() From fijal at codespeak.net Mon Mar 8 22:57:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 22:57:53 +0100 (CET) Subject: [pypy-svn] r71922 - pypy/trunk/pypy/tool Message-ID: <20100308215753.269E6282BD4@codespeak.net> Author: fijal Date: Mon Mar 8 22:57:51 2010 New Revision: 71922 Modified: pypy/trunk/pypy/tool/package.py Log: typo Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Mon Mar 8 22:57:51 2010 @@ -50,7 +50,7 @@ old_dir = os.getcwd() try: os.chdir(str(builddir)) - os.system("strip " + str(builddir.join('bin', 'pypy-c'))) + os.system("strip " + str(pypydir.join('bin', 'pypy-c'))) os.system('tar cvjf ' + str(builddir.join(name + '.tar.bz2')) + " " + name) finally: From fijal at codespeak.net Mon Mar 8 23:17:37 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 23:17:37 +0100 (CET) Subject: [pypy-svn] r71924 - in pypy/trunk/pypy/tool: . test Message-ID: <20100308221737.3E025282BD4@codespeak.net> Author: fijal Date: Mon Mar 8 23:17:35 2010 New Revision: 71924 Modified: pypy/trunk/pypy/tool/package.py pypy/trunk/pypy/tool/test/test_package.py Log: Don't include py subdirectory Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Mon Mar 8 23:17:35 2010 @@ -44,7 +44,7 @@ pypydir.ensure('pypy', dir=True) shutil.copytree(str(basedir.join('pypy', 'lib')), str(pypydir.join('pypy', 'lib')), - ignore=ignore_patterns('.svn')) + ignore=ignore_patterns('.svn', 'py')) pypydir.ensure('bin', dir=True) shutil.copy(str(pypy_c), str(pypydir.join('bin', 'pypy-c'))) old_dir = os.getcwd() Modified: pypy/trunk/pypy/tool/test/test_package.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_package.py (original) +++ pypy/trunk/pypy/tool/test/test_package.py Mon Mar 8 23:17:35 2010 @@ -17,6 +17,8 @@ assert builddir.join('test', 'lib-python', '2.5.2', 'test').check() assert builddir.join('test', 'bin', 'pypy-c').check() assert builddir.join('test', 'pypy', 'lib', 'syslog.py').check() + assert not builddir.join('test', 'pypy', 'lib', 'py').check() + assert not builddir.join('test', 'pypy', 'lib', 'ctypes_configure').check() th = tarfile.open(str(builddir.join('test.tar.bz2'))) assert th.getmember('test/pypy/lib/syslog.py') finally: From fijal at codespeak.net Mon Mar 8 23:21:32 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 8 Mar 2010 23:21:32 +0100 (CET) Subject: [pypy-svn] r71925 - pypy/build/ubuntu/debian Message-ID: <20100308222132.21075282BD4@codespeak.net> Author: fijal Date: Mon Mar 8 23:21:30 2010 New Revision: 71925 Modified: pypy/build/ubuntu/debian/Makefile.in Log: Fix options Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Mon Mar 8 23:21:30 2010 @@ -1,7 +1,7 @@ TARGET=pypy/translator/goal/targetpypystandalone TRANSLATE=pypy/translator/goal/translate.py -TRANSLATEOPTS=--batch --source -Ojit --jit-debug=0 +TRANSLATEOPTS=--batch --source -Ojit --jit-debug=off TARGETOPTS=%(TARGETOPTS)s PREFIX=%(PREFIX)s LOGIC=-o logic From arigo at codespeak.net Tue Mar 9 00:07:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 00:07:40 +0100 (CET) Subject: [pypy-svn] r71926 - pypy/trunk/pypy/translator/c/gcc/test/msvc Message-ID: <20100308230740.E2311282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 00:07:39 2010 New Revision: 71926 Added: pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s - copied, changed from r71873, pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s Log: Add a test: we cannot use -16(%ebp) as the location of the "push esi", because that's wrong, due to the rounding done by "and esp, xxx". Copied: pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s (from r71873, pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s) ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/elf/track6.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s Tue Mar 9 00:07:39 2010 @@ -1,26 +1,15 @@ - .type main, @function -main: - ;; a minimal example showing what kind of code gcc - ;; can produce for main(): some local variable accesses - ;; are relative to %ebp, while others are relative to - ;; %esp, and the difference %ebp-%esp is not constant - ;; because of the 'andl' to align the stack - pushl %ebp - movl %esp, %ebp - subl $8, %esp - andl $-16, %esp - movl $globalptr1, -4(%ebp) - movl $globalptr2, (%esp) - pushl $0 - call foobar - ;; expected {4(%ebp) | %ebx, %esi, %edi, (%ebp) | 4(%esp), -4(%ebp)} - popl %eax -#APP - /* GCROOT -4(%ebp) */ - /* GCROOT (%esp) */ -#NO_APP - movl %ebp, %esp - popl %ebp - ret +_TEXT SEGMENT +_pypy_g_foo PROC ; COMDAT - .size main, .-main + push ebp + mov ebp, esp + and esp, -64 + sub esp, 12 + push esi + call _pypy_g_something_else + ;; expected {4(%ebp) | %ebx, 0(%esp), %edi, (%ebp) | } + pop esi + mov esp, ebp + pop ebp + ret 0 +_pypy_g_foo ENDP From arigo at codespeak.net Tue Mar 9 00:08:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 00:08:43 +0100 (CET) Subject: [pypy-svn] r71927 - in pypy/trunk/pypy/translator/c/gcc: . test/msvc Message-ID: <20100308230843.57C97282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 00:08:41 2010 New Revision: 71927 Modified: pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Log: Fix the test of the previous checkin. Modified: pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s (original) +++ pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s Tue Mar 9 00:08:41 2010 @@ -7,7 +7,7 @@ sub esp, 12 push esi call _pypy_g_something_else - ;; expected {4(%ebp) | %ebx, 0(%esp), %edi, (%ebp) | } + ;; expected {4(%ebp) | %ebx, (%esp), %edi, (%ebp) | } pop esi mov esp, ebp pop ebp Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Tue Mar 9 00:08:41 2010 @@ -452,6 +452,8 @@ else: return self.binary_insn(line) + visit_and = visit_andl + def visit_leal(self, line): match = self.r_binaryinsn.match(line) target = match.group("target") From arigo at codespeak.net Tue Mar 9 00:13:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 00:13:53 +0100 (CET) Subject: [pypy-svn] r71928 - pypy/release/1.2.x/pypy/doc Message-ID: <20100308231353.8B0B2282BD7@codespeak.net> Author: arigo Date: Tue Mar 9 00:13:52 2010 New Revision: 71928 Modified: pypy/release/1.2.x/pypy/doc/download.txt Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71910:71911 Modified: pypy/release/1.2.x/pypy/doc/download.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/download.txt (original) +++ pypy/release/1.2.x/pypy/doc/download.txt Tue Mar 9 00:13:52 2010 @@ -2,28 +2,6 @@ Download one of the following release files: ============================================= -PyPy 1.2 Sources: ------------------ +Download page has moved to `pypy.org`_. -* `pypy-1.2.0.tar.bz2`_ (sources, unix line endings) or -* `pypy-1.2.0.tar.gz`_ (sources, unix line endings) or -* `pypy-1.2.0.zip`_ (sources, windows line-endings) - -.. _`pypy-1.2.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.bz2 -.. _`pypy-1.2.0.zip`: http://codespeak.net/download/pypy/pypy-1.2.0.zip -.. _`pypy-1.2.0.tar.gz`: http://codespeak.net/download/pypy/pypy-1.2.0.tar.gz - -Prebuilt binaries -~~~~~~~~~~~~~~~~~ - -XXX - -The ``lang`` repository -~~~~~~~~~~~~~~~~~~~~~~~ - -The ``lang`` part of our repository, which contains other interpreters -developped mostly as external contributions, has moved and is no longer -included in the above packages. You can grab it by `browsing the -Subversion source`__. - -.. __: http://codespeak.net/svn/pypy/lang/ +.. _`pypy.org`: http://pypy.org/download.html From arigo at codespeak.net Tue Mar 9 00:14:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 00:14:27 +0100 (CET) Subject: [pypy-svn] r71929 - in pypy/release/1.2.x/pypy/translator/c/gcc: . test/msvc Message-ID: <20100308231427.99901282BD7@codespeak.net> Author: arigo Date: Tue Mar 9 00:14:25 2010 New Revision: 71929 Added: pypy/release/1.2.x/pypy/translator/c/gcc/test/msvc/track6.s - copied unchanged from r71927, pypy/trunk/pypy/translator/c/gcc/test/msvc/track6.s Modified: pypy/release/1.2.x/pypy/translator/c/gcc/trackgcroot.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71925:71927 Modified: pypy/release/1.2.x/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/release/1.2.x/pypy/translator/c/gcc/trackgcroot.py Tue Mar 9 00:14:25 2010 @@ -450,6 +450,8 @@ else: return self.binary_insn(line) + visit_and = visit_andl + def visit_leal(self, line): match = self.r_binaryinsn.match(line) target = match.group("target") From fijal at codespeak.net Tue Mar 9 00:20:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 00:20:46 +0100 (CET) Subject: [pypy-svn] r71930 - pypy/trunk/pypy/tool Message-ID: <20100308232046.D6497282BD8@codespeak.net> Author: fijal Date: Tue Mar 9 00:20:45 2010 New Revision: 71930 Modified: pypy/trunk/pypy/tool/package.py Log: Ignore pyc files Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Tue Mar 9 00:20:45 2010 @@ -40,11 +40,11 @@ pypydir = builddir.ensure(name, dir=True) shutil.copytree(str(basedir.join('lib-python')), str(pypydir.join('lib-python')), - ignore=ignore_patterns('.svn')) + ignore=ignore_patterns('.svn', '*.pyc')) pypydir.ensure('pypy', dir=True) shutil.copytree(str(basedir.join('pypy', 'lib')), str(pypydir.join('pypy', 'lib')), - ignore=ignore_patterns('.svn', 'py')) + ignore=ignore_patterns('.svn', 'py', '*.pyc')) pypydir.ensure('bin', dir=True) shutil.copy(str(pypy_c), str(pypydir.join('bin', 'pypy-c'))) old_dir = os.getcwd() From fijal at codespeak.net Tue Mar 9 01:07:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 01:07:20 +0100 (CET) Subject: [pypy-svn] r71940 - pypy/build/bot2/pypybuildbot Message-ID: <20100309000720.03AB95105D@codespeak.net> Author: fijal Date: Tue Mar 9 01:07:19 2010 New Revision: 71940 Modified: pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/master.py Log: remove maemo build - it seems without a real device it's pointless and nobody cared about setting up a real device enough Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Tue Mar 9 01:07:19 2010 @@ -161,31 +161,3 @@ description="run benchmarks 1", command=["python", "pypy/translator/benchmark/jitbench.py", "pypy/translator/goal/pypy-c"])) - -# xxx keep style -class TranslatedScratchbox(factory.BuildFactory): - def __init__(self, *a, **kw): - USERNAME = 'buildbot' - WORKDIR = '/scratchbox/users/%s/home/%s/build' % (USERNAME, USERNAME) - - factory.BuildFactory.__init__(self, *a, **kw) - platform = kw.pop('platform', 'linux') - setup_steps(platform, self, WORKDIR) - workdir = os.path.join(WORKDIR, 'pypy', 'translator', 'goal') - - self.addStep(Translate(["--platform", "maemo", "--gc=hybrid", "-Omem"], - [], workdir=workdir)) - - #self.addStep(ShellCmd( - # description="app-level (-A) test", - # command=["python", "testrunner/scratchbox_runner.py", - # "--logfile=pytest-A.log", - # "--config=pypy/pytest-A.cfg", - # "--root=pypy", "--timeout=1800"], - # logfiles={'pytestLog': 'pytest-A.log'}, - # timeout = 4000, - # workdir = WORKDIR, - # env={"PYTHONPATH": ['.']})) - self.addStep(ShellCmd( - description="copy build", - command=["scp", "pypy-c", "fijal at codespeak.net:builds/pypy-c-scratchbox"], workdir = workdir)) Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Tue Mar 9 01:07:19 2010 @@ -44,7 +44,7 @@ 'stackless', 'windows', 'mac', 'benchmark-run', - 'maemo', 'other'])) + 'other'])) pypybuilds = load('pypybuildbot.builds') @@ -97,9 +97,6 @@ pypyJITBenchmarkFactory = pypybuilds.JITBenchmark() -pypyTranslatedLibPythonMaemoTestFactory = pypybuilds.TranslatedScratchbox() - - LINUX32 = "own-linux-x86-32" MACOSX32 = "own-macosx-x86-32" APPLVLLINUX32 = "pypy-c-app-level-linux-x86-32" @@ -116,8 +113,6 @@ JITONLYLINUX32 = "jitonly-own-linux-x86-32" JITBENCH = "jit-benchmark-linux-x86-32" -BUILDMAEMO = "pypy-c-maemo-build" - BuildmasterConfig = { 'slavePortnum': slavePortnum, @@ -175,12 +170,6 @@ "factory": pypyTranslatedAppLevelTestFactoryWin, "category": "windows" }, - {"name" : BUILDMAEMO, - "slavenames": ['bigdogvm1'], - "builddir" : BUILDMAEMO, - "factory": pypyTranslatedLibPythonMaemoTestFactory, - "category": 'maemo' - }, {"name" : APPLVLFREEBSD64, "slavenames": ['headless'], 'builddir' : APPLVLFREEBSD64, From fijal at codespeak.net Tue Mar 9 01:11:38 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 01:11:38 +0100 (CET) Subject: [pypy-svn] r71941 - in pypy/branch/import-fiddle/pypy/module/pypyjit: . test Message-ID: <20100309001138.5CC365105E@codespeak.net> Author: fijal Date: Tue Mar 9 01:11:36 2010 New Revision: 71941 Modified: pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py pypy/branch/import-fiddle/pypy/module/pypyjit/test/test_policy.py Log: Be a bit more careful about looking into places and a test Modified: pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py (original) +++ pypy/branch/import-fiddle/pypy/module/pypyjit/policy.py Tue Mar 9 01:11:36 2010 @@ -8,11 +8,12 @@ modname == '__builtin__.interp_classobj' or modname == '__builtin__.functional'): return True - + if modname == 'sys.state': + return True if '.' in modname: modname, _ = modname.split('.', 1) if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', - 'sys', 'imp']: + 'imp']: return True return False Modified: pypy/branch/import-fiddle/pypy/module/pypyjit/test/test_policy.py ============================================================================== --- pypy/branch/import-fiddle/pypy/module/pypyjit/test/test_policy.py (original) +++ pypy/branch/import-fiddle/pypy/module/pypyjit/test/test_policy.py Tue Mar 9 01:11:36 2010 @@ -32,7 +32,7 @@ assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst') assert pypypolicy.look_inside_pypy_module('__builtin__.functional') assert pypypolicy.look_inside_pypy_module('exceptions.interp_exceptions') - for modname in 'pypyjit', 'signal', 'micronumpy', 'math': + for modname in 'pypyjit', 'signal', 'micronumpy', 'math', 'imp': assert pypypolicy.look_inside_pypy_module(modname) assert pypypolicy.look_inside_pypy_module(modname + '.foo') @@ -42,3 +42,4 @@ def test_module_with_stuff_in_init(): from pypy.module.sys import Module assert not pypypolicy.look_inside_function(Module.getdictvalue.im_func) + From fijal at codespeak.net Tue Mar 9 01:19:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 01:19:21 +0100 (CET) Subject: [pypy-svn] r71942 - pypy/build/ubuntu/debian Message-ID: <20100309001921.681BD5105F@codespeak.net> Author: fijal Date: Tue Mar 9 01:19:19 2010 New Revision: 71942 Modified: pypy/build/ubuntu/debian/Makefile.in Log: Set environment var, so the usession dir is actually what it's named (can be arbitrary though) Modified: pypy/build/ubuntu/debian/Makefile.in ============================================================================== --- pypy/build/ubuntu/debian/Makefile.in (original) +++ pypy/build/ubuntu/debian/Makefile.in Tue Mar 9 01:19:19 2010 @@ -42,7 +42,7 @@ bin/pypy: @rm -rf $(TMPDIR) mkdir $(TMPDIR) - $(TRANSLATE) $(TRANSLATEOPTS) $(TARGET) $(TARGETOPTS) + PYPY_USESSION_BASENAME='-' $(TRANSLATE) $(TRANSLATEOPTS) $(TARGET) $(TARGETOPTS) make -C $(TMPDIR)/usession-0/testing_1 install -D $(TMPDIR)/usession-0/testing_1/testing_1 $@ From dan at codespeak.net Tue Mar 9 02:09:59 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Tue, 9 Mar 2010 02:09:59 +0100 (CET) Subject: [pypy-svn] r71943 - in pypy/branch/micronumpy/pypy/module/micronumpy: . test Message-ID: <20100309010959.6240451061@codespeak.net> Author: dan Date: Tue Mar 9 02:09:57 2010 New Revision: 71943 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: Minor housecleaning, improved mdarray setitem test. Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Tue Mar 9 02:09:57 2010 @@ -104,10 +104,10 @@ newextract = make_sure_not_resized([0]*len(extract)*factor) prestride = strides[i-1] for j in range(len(extract)): - jf = j*factor + jf = j * factor st = extract[j] for k in range(factor): - newextract[jf+k] = st + start + newextract[jf + k] = st + start st += prestride extract = newextract #No adding for shape @@ -121,15 +121,15 @@ class BaseMultiDimArray(BaseNumArray): pass def descr_dtype(space, self): - return self.dtype + return space.wrap(self.dtype) def descr_shape(space, self): return space.newtuple([space.wrap(dim) for dim in self.shape]) -MUL = mul_operation() -DIV = div_operation() -ADD = add_operation() -SUB = sub_operation() +mul = mul_operation() +div = div_operation() +add = add_operation() +sub = sub_operation() def create_mdarray(data_type, unwrap, coerce): @@ -202,18 +202,17 @@ client_fixedview = {} client_scalar['mul'], client_fixedview['mul'] = \ - create_client_math_operation(MUL) + create_client_math_operation(mul) client_scalar['div'], client_fixedview['div'] = \ - create_client_math_operation(DIV) + create_client_math_operation(div) client_scalar['add'], client_fixedview['add'] = \ - create_client_math_operation(ADD) + create_client_math_operation(add) client_scalar['sub'], client_fixedview['sub'] = \ - create_client_math_operation(SUB) - descr_mul = create_math_operation(MUL) - descr_div = create_math_operation(DIV) - descr_add = create_math_operation(ADD) - descr_sub = create_math_operation(SUB) - + create_client_math_operation(sub) + descr_mul = create_math_operation(mul) + descr_div = create_math_operation(div) + descr_add = create_math_operation(add) + descr_sub = create_math_operation(sub) def load_iterable(self, w_xs): self._internal_load(w_xs, self.shape, []) @@ -254,6 +253,15 @@ def descr_getitem(self, w_index): space = self.space + + try: + field_name = space.str_w(w_index) + raise OperationError(space.w_ValueError, #FIXME: if we were honest this would be NotImplemented + space.wrap("field name %s not found" % field_name)) + except OperationError, e: + if not e.match(space, space.w_TypeError): + raise + try: space.iter(w_index) except OperationError, e: @@ -306,34 +314,31 @@ raise value = coerce(space, w_value) for start in regions: - self.storage[start:start+lslice]=[value]*lslice + self.storage[start:start + lslice] = [value] * lslice return arr = array_fromseq(space, w_value, None) ls = len(arr.shape) lss = len(shape) if not (ls <= lss and list(arr.shape) == shape[lss-ls:lss]): - raise OperationError(space.w_ValueError, + raise OperationError(space.w_ValueError, #FIXME: throws when it shouldn't space.wrap('array dimensions ' 'are not compatible for copy')) - #exactly as in numpy - # /S\ - DO NOT EDIT if you're not sure! #we may exit earlier, but we are true purists and wonna check if len(regions) == 0: return l = len(arr.storage) if lslice > l: #long slice - iters = lslice//l - assert lslice == l*iters + iters = lslice // l + assert lslice == l * iters for start in regions: for i in range(iters): - self.storage[start:start+l] = arr.storage + self.storage[start:start + l] = arr.storage start += l else: i = 0 for start in regions: - self.storage[start:start+l] = arr.storage[i:i+lslice] + self.storage[start:start + l] = arr.storage[i:i + lslice] if i > l: i = i-l - #Looks like perfect else: pos = compute_pos(space, indexes, self.shape) self.storage[pos] = coerce(space, w_value) Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Tue Mar 9 02:09:57 2010 @@ -220,15 +220,15 @@ if e.match(space, space.w_TypeError): raise OperationError(space.w_ValueError, space.wrap("can't understand index")) #FIXME: more meaningful message based on type - try: - self.storage[index] = coerce(space, w_value) - except OperationError, e: - if e.match(space, space.w_TypeError): - raise OperationError(space.w_ValueError, - space.wrap("can't understand value")) #FIXME: more meaningful message based on type - except IndexError: - raise OperationError(space.w_IndexError, - space.wrap("list index out of range")) + try: + self.storage[index] = coerce(space, w_value) + except OperationError, e: + if e.match(space, space.w_TypeError): + raise OperationError(space.w_ValueError, + space.wrap("can't understand value")) #FIXME: more meaningful message based on type + except IndexError: + raise OperationError(space.w_IndexError, + space.wrap("list index out of range")) return space.w_None descr_setitem.unwrap_spec = ['self', W_Root, W_Root] Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Tue Mar 9 02:09:57 2010 @@ -65,7 +65,6 @@ from operator import mul, div, add, sub compare = self.compare d = range(1, self.length) - #skip('overkill...') for data_type in (int, float): data = [data_type(x) for x in d] ar = array(data) @@ -302,7 +301,7 @@ #setitem ar[2] = 3 assert ar[2, 0] == ar[2, 1] == ar[2, 2] == 3 - ar[2:3] == [1] #FIXME: this probably throws + ar[2:3] = [7] ar[2] = [0, 1, 2] assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) From arigo at codespeak.net Tue Mar 9 13:37:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 13:37:06 +0100 (CET) Subject: [pypy-svn] r71944 - in pypy/trunk/pypy: rlib rpython/lltypesystem translator/platform translator/tool Message-ID: <20100309123706.B2C7B5105D@codespeak.net> Author: arigo Date: Tue Mar 9 13:37:04 2010 New Revision: 71944 Modified: pypy/trunk/pypy/rlib/libffi.py pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py pypy/trunk/pypy/translator/platform/linux.py pypy/trunk/pypy/translator/tool/cbuild.py Log: Make pypy-c translations contain a static libffi on Linux. Avoids the troubles of finding the dynamic libffi.so, and anyway it's quite small. Modified: pypy/trunk/pypy/rlib/libffi.py ============================================================================== --- pypy/trunk/pypy/rlib/libffi.py (original) +++ pypy/trunk/pypy/rlib/libffi.py Tue Mar 9 13:37:04 2010 @@ -53,11 +53,13 @@ separate_module_sources = [] if not _MSVC: + # On some platforms, we try to link statically libffi, which is small + # anyway and avoids endless troubles for installing. On other platforms + # libffi.a is typically not there, so we link dynamically. if _MINGW: includes = ['windows.h', 'ffi.h'] else: includes = ['dlfcn.h', 'ffi.h'] - include_dirs = platform.include_dirs_for_libffi() if _MAC_OS: pre_include_bits = ['#define MACOSX'] @@ -65,9 +67,25 @@ pre_include_bits = [] if _FREEBSD_7 or _MINGW: - libraries = ['ffi'] + libraries = [] else: - libraries = ['ffi', 'dl'] + libraries = ['dl'] + + def find_libffi_a(): + dirlist = platform.library_dirs_for_libffi_a() + for dir in dirlist: + result = os.path.join(dir, 'libffi.a') + if os.path.exists(result): + return result + raise ImportError("'libffi.a' not found in %s" % (dirlist,)) + + if hasattr(platform, 'library_dirs_for_libffi_a'): + # platforms on which we want static linking + link_files = [find_libffi_a()] + else: + # platforms on which we want dynamic linking + libraries = ['ffi'] + libraries + link_files = [] eci = ExternalCompilationInfo( pre_include_bits = pre_include_bits, @@ -76,6 +94,8 @@ separate_module_sources = separate_module_sources, include_dirs = platform.include_dirs_for_libffi(), library_dirs = platform.library_dirs_for_libffi(), + link_files = link_files, + testonly_libraries = ['ffi'], ) else: libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc') Modified: pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py Tue Mar 9 13:37:04 2010 @@ -853,7 +853,7 @@ eci = old_eci.compile_shared_lib() _eci_cache[old_eci] = eci - libraries = list(eci.libraries + eci.frameworks) + libraries = eci.testonly_libraries + eci.libraries + eci.frameworks FUNCTYPE = lltype.typeOf(funcptr).TO if not libraries: Modified: pypy/trunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/trunk/pypy/translator/platform/linux.py (original) +++ pypy/trunk/pypy/translator/platform/linux.py Tue Mar 9 13:37:04 2010 @@ -24,6 +24,10 @@ def library_dirs_for_libffi(self): return ['/usr/lib/libffi'] + def library_dirs_for_libffi_a(self): + # places where we need to look for libffi.a + return self.library_dirs_for_libffi() + ['/usr/lib'] + class Linux64(Linux): shared_only = ['-fPIC'] Modified: pypy/trunk/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/trunk/pypy/translator/tool/cbuild.py (original) +++ pypy/trunk/pypy/translator/tool/cbuild.py Tue Mar 9 13:37:04 2010 @@ -18,7 +18,7 @@ 'post_include_bits', 'libraries', 'library_dirs', 'separate_module_sources', 'separate_module_files', 'export_symbols', 'compile_extra', 'link_extra', - 'frameworks', 'link_files'] + 'frameworks', 'link_files', 'testonly_libraries'] _DUPLICATES_OK = ['compile_extra', 'link_extra'] _EXTRA_ATTRIBUTES = ['use_cpp_linker', 'platform'] @@ -36,6 +36,7 @@ link_extra = [], frameworks = [], link_files = [], + testonly_libraries = [], use_cpp_linker = False, platform = None): """ @@ -82,6 +83,10 @@ link_files: list of file names which will be directly passed to the linker + testonly_libraries: list of libraries that are searched for during + testing only, by ll2ctypes. Useful to search for a name in a dynamic + library during testing but use the static library for compilation. + use_cpp_linker: a flag to tell if g++ should be used instead of gcc when linking (a bit custom so far) From arigo at codespeak.net Tue Mar 9 13:43:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 13:43:37 +0100 (CET) Subject: [pypy-svn] r71945 - in pypy/release/1.2.x/pypy: rlib rpython/lltypesystem translator/platform translator/tool Message-ID: <20100309124337.095AE5105D@codespeak.net> Author: arigo Date: Tue Mar 9 13:43:36 2010 New Revision: 71945 Modified: pypy/release/1.2.x/pypy/rlib/libffi.py pypy/release/1.2.x/pypy/rpython/lltypesystem/ll2ctypes.py pypy/release/1.2.x/pypy/translator/platform/linux.py pypy/release/1.2.x/pypy/translator/tool/cbuild.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71943:71944 Modified: pypy/release/1.2.x/pypy/rlib/libffi.py ============================================================================== --- pypy/release/1.2.x/pypy/rlib/libffi.py (original) +++ pypy/release/1.2.x/pypy/rlib/libffi.py Tue Mar 9 13:43:36 2010 @@ -53,11 +53,13 @@ separate_module_sources = [] if not _MSVC: + # On some platforms, we try to link statically libffi, which is small + # anyway and avoids endless troubles for installing. On other platforms + # libffi.a is typically not there, so we link dynamically. if _MINGW: includes = ['windows.h', 'ffi.h'] else: includes = ['dlfcn.h', 'ffi.h'] - include_dirs = platform.include_dirs_for_libffi() if _MAC_OS: pre_include_bits = ['#define MACOSX'] @@ -65,9 +67,25 @@ pre_include_bits = [] if _FREEBSD_7 or _MINGW: - libraries = ['ffi'] + libraries = [] else: - libraries = ['ffi', 'dl'] + libraries = ['dl'] + + def find_libffi_a(): + dirlist = platform.library_dirs_for_libffi_a() + for dir in dirlist: + result = os.path.join(dir, 'libffi.a') + if os.path.exists(result): + return result + raise ImportError("'libffi.a' not found in %s" % (dirlist,)) + + if hasattr(platform, 'library_dirs_for_libffi_a'): + # platforms on which we want static linking + link_files = [find_libffi_a()] + else: + # platforms on which we want dynamic linking + libraries = ['ffi'] + libraries + link_files = [] eci = ExternalCompilationInfo( pre_include_bits = pre_include_bits, @@ -76,6 +94,8 @@ separate_module_sources = separate_module_sources, include_dirs = platform.include_dirs_for_libffi(), library_dirs = platform.library_dirs_for_libffi(), + link_files = link_files, + testonly_libraries = ['ffi'], ) else: libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc') Modified: pypy/release/1.2.x/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/release/1.2.x/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/release/1.2.x/pypy/rpython/lltypesystem/ll2ctypes.py Tue Mar 9 13:43:36 2010 @@ -853,7 +853,7 @@ eci = old_eci.compile_shared_lib() _eci_cache[old_eci] = eci - libraries = list(eci.libraries + eci.frameworks) + libraries = eci.testonly_libraries + eci.libraries + eci.frameworks FUNCTYPE = lltype.typeOf(funcptr).TO if not libraries: Modified: pypy/release/1.2.x/pypy/translator/platform/linux.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/platform/linux.py (original) +++ pypy/release/1.2.x/pypy/translator/platform/linux.py Tue Mar 9 13:43:36 2010 @@ -24,6 +24,10 @@ def library_dirs_for_libffi(self): return ['/usr/lib/libffi'] + def library_dirs_for_libffi_a(self): + # places where we need to look for libffi.a + return self.library_dirs_for_libffi() + ['/usr/lib'] + class Linux64(Linux): shared_only = ['-fPIC'] Modified: pypy/release/1.2.x/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/tool/cbuild.py (original) +++ pypy/release/1.2.x/pypy/translator/tool/cbuild.py Tue Mar 9 13:43:36 2010 @@ -18,7 +18,7 @@ 'post_include_bits', 'libraries', 'library_dirs', 'separate_module_sources', 'separate_module_files', 'export_symbols', 'compile_extra', 'link_extra', - 'frameworks', 'link_files'] + 'frameworks', 'link_files', 'testonly_libraries'] _DUPLICATES_OK = ['compile_extra', 'link_extra'] _EXTRA_ATTRIBUTES = ['use_cpp_linker', 'platform'] @@ -36,6 +36,7 @@ link_extra = [], frameworks = [], link_files = [], + testonly_libraries = [], use_cpp_linker = False, platform = None): """ @@ -82,6 +83,10 @@ link_files: list of file names which will be directly passed to the linker + testonly_libraries: list of libraries that are searched for during + testing only, by ll2ctypes. Useful to search for a name in a dynamic + library during testing but use the static library for compilation. + use_cpp_linker: a flag to tell if g++ should be used instead of gcc when linking (a bit custom so far) From arigo at codespeak.net Tue Mar 9 14:25:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 14:25:00 +0100 (CET) Subject: [pypy-svn] r71950 - pypy/trunk/pypy/tool Message-ID: <20100309132500.AE685282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 14:24:59 2010 New Revision: 71950 Modified: pypy/trunk/pypy/tool/package.py Log: Also ignore the files "*~". Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Tue Mar 9 14:24:59 2010 @@ -40,11 +40,11 @@ pypydir = builddir.ensure(name, dir=True) shutil.copytree(str(basedir.join('lib-python')), str(pypydir.join('lib-python')), - ignore=ignore_patterns('.svn', '*.pyc')) + ignore=ignore_patterns('.svn', '*.pyc', '*~')) pypydir.ensure('pypy', dir=True) shutil.copytree(str(basedir.join('pypy', 'lib')), str(pypydir.join('pypy', 'lib')), - ignore=ignore_patterns('.svn', 'py', '*.pyc')) + ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~')) pypydir.ensure('bin', dir=True) shutil.copy(str(pypy_c), str(pypydir.join('bin', 'pypy-c'))) old_dir = os.getcwd() From arigo at codespeak.net Tue Mar 9 14:30:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 14:30:08 +0100 (CET) Subject: [pypy-svn] r71951 - pypy/trunk/pypy/tool Message-ID: <20100309133008.C5F69282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 14:30:07 2010 New Revision: 71951 Modified: pypy/trunk/pypy/tool/package.py Log: Write down a warning explicitly. Modified: pypy/trunk/pypy/tool/package.py ============================================================================== --- pypy/trunk/pypy/tool/package.py (original) +++ pypy/trunk/pypy/tool/package.py Tue Mar 9 14:30:07 2010 @@ -41,6 +41,8 @@ shutil.copytree(str(basedir.join('lib-python')), str(pypydir.join('lib-python')), ignore=ignore_patterns('.svn', '*.pyc', '*~')) + # Careful: to copy pypy/lib, copying just the svn-tracked files + # would not be enough: there are also ctypes_config_cache/_*_cache.py. pypydir.ensure('pypy', dir=True) shutil.copytree(str(basedir.join('pypy', 'lib')), str(pypydir.join('pypy', 'lib')), From arigo at codespeak.net Tue Mar 9 14:35:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 14:35:40 +0100 (CET) Subject: [pypy-svn] r71952 - pypy/trunk Message-ID: <20100309133540.DA320282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 14:35:39 2010 New Revision: 71952 Modified: pypy/trunk/README Log: Update README. Modified: pypy/trunk/README ============================================================================== --- pypy/trunk/README (original) +++ pypy/trunk/README Tue Mar 9 14:35:39 2010 @@ -9,11 +9,15 @@ You can build self-contained Python implementations which execute independently from CPython. +The home page is: + + http://pypy.org/ + We invite you to head over to our detailed getting-started document: pypy/doc/getting-started.html or pypy/doc/getting-started.txt - (local if you got a tarball or svn checkout) + (local if you got a source tarball or svn checkout) http://codespeak.net/pypy/dist/pypy/doc/getting-started.html From arigo at codespeak.net Tue Mar 9 15:14:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 15:14:31 +0100 (CET) Subject: [pypy-svn] r71954 - in pypy/trunk: ctypes_configure pypy/lib/ctypes_config_cache Message-ID: <20100309141431.0094E282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 15:14:30 2010 New Revision: 71954 Modified: pypy/trunk/ctypes_configure/dumpcache.py pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py Log: Copy the list of constant names from CPython's _localemodule.c instead of having a guessed-up list with both too many names (does not compile) and too little, on other platforms. Modified: pypy/trunk/ctypes_configure/dumpcache.py ============================================================================== --- pypy/trunk/ctypes_configure/dumpcache.py (original) +++ pypy/trunk/ctypes_configure/dumpcache.py Tue Mar 9 15:14:30 2010 @@ -10,6 +10,8 @@ print >> f names = config.keys() names.sort() + print >> f, '__all__ = %r' % (tuple(names),) + print >> f for key in names: val = config[key] if isinstance(val, (int, long)): Modified: pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py Tue Mar 9 15:14:30 2010 @@ -10,37 +10,40 @@ # ____________________________________________________________ -_CONSTANTS = ( +_CONSTANTS = [ 'LC_CTYPE', - 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', + 'LC_NUMERIC', 'LC_ALL', - 'LC_PAPER', - 'LC_NAME', - 'LC_ADDRESS', - 'LC_TELEPHONE', - 'LC_MEASUREMENT', - 'LC_IDENTIFICATION', -) + 'CHAR_MAX', +] class LocaleConfigure: _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) + setattr(LocaleConfigure, key, DefinedConstantInteger(key)) config = configure(LocaleConfigure, noerr=True) +for key, value in config.items(): + if value is None: + del config[key] + _CONSTANTS.remove(key) # ____________________________________________________________ HAS_LANGINFO = True # xxx hard-coded to True for now if HAS_LANGINFO: - # this is incomplete list - langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' - 'YESEXPR NOEXPR CRNCYSTR').split(" ") + # list of all possible names + langinfo_names = [ + "RADIXCHAR", "THOUSEP", "CRNCYSTR", + "D_T_FMT", "D_FMT", "T_FMT", "AM_STR", "PM_STR", + "CODESET", "T_FMT_AMPM", "ERA", "ERA_D_FMT", "ERA_D_T_FMT", + "ERA_T_FMT", "ALT_DIGITS", "YESEXPR", "NOEXPR", "_DATE_FMT", + ] for i in range(1, 8): langinfo_names.append("DAY_%d" % i) langinfo_names.append("ABDAY_%d" % i) @@ -52,13 +55,18 @@ _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) nl_item = SimpleType('nl_item') for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) + setattr(LanginfoConfigure, key, DefinedConstantInteger(key)) - config.update(configure(LanginfoConfigure)) - _CONSTANTS = _CONSTANTS + tuple(langinfo_names) + langinfo_config = configure(LanginfoConfigure) + for key, value in langinfo_config.items(): + if value is None: + del langinfo_config[key] + langinfo_names.remove(key) + config.update(langinfo_config) + _CONSTANTS += langinfo_names # ____________________________________________________________ -config['ALL_CONSTANTS'] = _CONSTANTS +config['ALL_CONSTANTS'] = tuple(_CONSTANTS) config['HAS_LANGINFO'] = HAS_LANGINFO dumpcache(__file__, '_locale_cache.py', config) From arigo at codespeak.net Tue Mar 9 15:21:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 15:21:03 +0100 (CET) Subject: [pypy-svn] r71955 - pypy/trunk/pypy/lib/ctypes_config_cache Message-ID: <20100309142103.42FD2282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 15:21:02 2010 New Revision: 71955 Modified: pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py Log: Detect HAS_LANGINFO. Modified: pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py Tue Mar 9 15:21:02 2010 @@ -5,7 +5,7 @@ import autopath from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + ConstantInteger, DefinedConstantInteger, SimpleType, check_eci) from ctypes_configure.dumpcache import dumpcache # ____________________________________________________________ @@ -34,7 +34,8 @@ # ____________________________________________________________ -HAS_LANGINFO = True # xxx hard-coded to True for now +eci = ExternalCompilationInfo(includes=['langinfo.h']) +HAS_LANGINFO = check_eci(eci) if HAS_LANGINFO: # list of all possible names @@ -52,7 +53,7 @@ langinfo_names.append("ABMON_%d" % i) class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) + _compilation_info_ = eci nl_item = SimpleType('nl_item') for key in langinfo_names: setattr(LanginfoConfigure, key, DefinedConstantInteger(key)) From arigo at codespeak.net Tue Mar 9 15:25:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 15:25:54 +0100 (CET) Subject: [pypy-svn] r71956 - in pypy/release/1.2.x: . ctypes_configure pypy/lib/ctypes_config_cache Message-ID: <20100309142554.7DEB5282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 15:25:52 2010 New Revision: 71956 Modified: pypy/release/1.2.x/README pypy/release/1.2.x/ctypes_configure/dumpcache.py pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71951:71955 Modified: pypy/release/1.2.x/README ============================================================================== --- pypy/release/1.2.x/README (original) +++ pypy/release/1.2.x/README Tue Mar 9 15:25:52 2010 @@ -9,11 +9,15 @@ You can build self-contained Python implementations which execute independently from CPython. +The home page is: + + http://pypy.org/ + We invite you to head over to our detailed getting-started document: pypy/doc/getting-started.html or pypy/doc/getting-started.txt - (local if you got a tarball or svn checkout) + (local if you got a source tarball or svn checkout) http://codespeak.net/pypy/dist/pypy/doc/getting-started.html Modified: pypy/release/1.2.x/ctypes_configure/dumpcache.py ============================================================================== --- pypy/release/1.2.x/ctypes_configure/dumpcache.py (original) +++ pypy/release/1.2.x/ctypes_configure/dumpcache.py Tue Mar 9 15:25:52 2010 @@ -10,6 +10,8 @@ print >> f names = config.keys() names.sort() + print >> f, '__all__ = %r' % (tuple(names),) + print >> f for key in names: val = config[key] if isinstance(val, (int, long)): Modified: pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py Tue Mar 9 15:25:52 2010 @@ -5,42 +5,46 @@ import autopath from ctypes_configure.configure import (configure, ExternalCompilationInfo, - ConstantInteger, DefinedConstantInteger, SimpleType) + ConstantInteger, DefinedConstantInteger, SimpleType, check_eci) from ctypes_configure.dumpcache import dumpcache # ____________________________________________________________ -_CONSTANTS = ( +_CONSTANTS = [ 'LC_CTYPE', - 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', + 'LC_NUMERIC', 'LC_ALL', - 'LC_PAPER', - 'LC_NAME', - 'LC_ADDRESS', - 'LC_TELEPHONE', - 'LC_MEASUREMENT', - 'LC_IDENTIFICATION', -) + 'CHAR_MAX', +] class LocaleConfigure: _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) for key in _CONSTANTS: - setattr(LocaleConfigure, key, ConstantInteger(key)) + setattr(LocaleConfigure, key, DefinedConstantInteger(key)) config = configure(LocaleConfigure, noerr=True) +for key, value in config.items(): + if value is None: + del config[key] + _CONSTANTS.remove(key) # ____________________________________________________________ -HAS_LANGINFO = True # xxx hard-coded to True for now +eci = ExternalCompilationInfo(includes=['langinfo.h']) +HAS_LANGINFO = check_eci(eci) if HAS_LANGINFO: - # this is incomplete list - langinfo_names = ('CODESET D_T_FMT D_FMT T_FMT RADIXCHAR THOUSEP ' - 'YESEXPR NOEXPR CRNCYSTR').split(" ") + # list of all possible names + langinfo_names = [ + "RADIXCHAR", "THOUSEP", "CRNCYSTR", + "D_T_FMT", "D_FMT", "T_FMT", "AM_STR", "PM_STR", + "CODESET", "T_FMT_AMPM", "ERA", "ERA_D_FMT", "ERA_D_T_FMT", + "ERA_T_FMT", "ALT_DIGITS", "YESEXPR", "NOEXPR", "_DATE_FMT", + ] for i in range(1, 8): langinfo_names.append("DAY_%d" % i) langinfo_names.append("ABDAY_%d" % i) @@ -49,16 +53,21 @@ langinfo_names.append("ABMON_%d" % i) class LanginfoConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['langinfo.h']) + _compilation_info_ = eci nl_item = SimpleType('nl_item') for key in langinfo_names: - setattr(LanginfoConfigure, key, ConstantInteger(key)) + setattr(LanginfoConfigure, key, DefinedConstantInteger(key)) - config.update(configure(LanginfoConfigure)) - _CONSTANTS = _CONSTANTS + tuple(langinfo_names) + langinfo_config = configure(LanginfoConfigure) + for key, value in langinfo_config.items(): + if value is None: + del langinfo_config[key] + langinfo_names.remove(key) + config.update(langinfo_config) + _CONSTANTS += langinfo_names # ____________________________________________________________ -config['ALL_CONSTANTS'] = _CONSTANTS +config['ALL_CONSTANTS'] = tuple(_CONSTANTS) config['HAS_LANGINFO'] = HAS_LANGINFO dumpcache(__file__, '_locale_cache.py', config) From arigo at codespeak.net Tue Mar 9 15:28:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 15:28:36 +0100 (CET) Subject: [pypy-svn] r71957 - pypy/trunk/pypy/lib Message-ID: <20100309142836.23891282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 15:28:35 2010 New Revision: 71957 Modified: pypy/trunk/pypy/lib/_locale.py Log: Bah. This now comes from ctypes_config_cache/_locale_cache.py. Modified: pypy/trunk/pypy/lib/_locale.py ============================================================================== --- pypy/trunk/pypy/lib/_locale.py (original) +++ pypy/trunk/pypy/lib/_locale.py Tue Mar 9 15:28:35 2010 @@ -14,9 +14,6 @@ size_t = c_int -# XXX check where this comes from -CHAR_MAX = 127 - # Ubuntu Gusty i386 structure class lconv(Structure): @@ -313,7 +310,7 @@ 'Error', 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', - 'bindtextdomain', 'CHAR_MAX', + 'bindtextdomain', ) + ALL_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) From arigo at codespeak.net Tue Mar 9 15:29:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 15:29:17 +0100 (CET) Subject: [pypy-svn] r71958 - pypy/release/1.2.x/pypy/lib Message-ID: <20100309142917.631C5282BD4@codespeak.net> Author: arigo Date: Tue Mar 9 15:29:16 2010 New Revision: 71958 Modified: pypy/release/1.2.x/pypy/lib/_locale.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71956:71957 Modified: pypy/release/1.2.x/pypy/lib/_locale.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/_locale.py (original) +++ pypy/release/1.2.x/pypy/lib/_locale.py Tue Mar 9 15:29:16 2010 @@ -14,9 +14,6 @@ size_t = c_int -# XXX check where this comes from -CHAR_MAX = 127 - # Ubuntu Gusty i386 structure class lconv(Structure): @@ -313,7 +310,7 @@ 'Error', 'setlocale', 'localeconv', 'strxfrm', 'strcoll', 'gettext', 'dgettext', 'dcgettext', 'textdomain', - 'bindtextdomain', 'CHAR_MAX', + 'bindtextdomain', ) + ALL_CONSTANTS if _bind_textdomain_codeset: __all__ += ('bind_textdomain_codeset',) From benjamin at codespeak.net Tue Mar 9 15:44:57 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 9 Mar 2010 15:44:57 +0100 (CET) Subject: [pypy-svn] r71959 - pypy/trunk/pypy/lib/app_test Message-ID: <20100309144457.51EE0282BD5@codespeak.net> Author: benjamin Date: Tue Mar 9 15:44:55 2010 New Revision: 71959 Modified: pypy/trunk/pypy/lib/app_test/test_binascii.py (props changed) Log: this file doesn't have a shebang line to execute From benjamin at codespeak.net Tue Mar 9 15:46:16 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 9 Mar 2010 15:46:16 +0100 (CET) Subject: [pypy-svn] r71960 - in pypy/trunk/pypy: doc/config doc/discussion lib module/_collections module/_collections/test module/imp module/imp/test module/oracle module/oracle/test translator/benchmark Message-ID: <20100309144616.A86B8282BD5@codespeak.net> Author: benjamin Date: Tue Mar 9 15:46:14 2010 New Revision: 71960 Modified: pypy/trunk/pypy/doc/config/objspace.usemodules.imp.txt (contents, props changed) pypy/trunk/pypy/doc/config/translation.jit_profiler.txt (props changed) pypy/trunk/pypy/doc/discussion/improve-rpython.txt (contents, props changed) pypy/trunk/pypy/lib/PyQt4.py (props changed) pypy/trunk/pypy/lib/_rpyc_support.py (props changed) pypy/trunk/pypy/lib/sip.py (props changed) pypy/trunk/pypy/module/_collections/__init__.py (contents, props changed) pypy/trunk/pypy/module/_collections/interp_collection.py (contents, props changed) pypy/trunk/pypy/module/_collections/test/__init__.py (props changed) pypy/trunk/pypy/module/_collections/test/test_collection.py (contents, props changed) pypy/trunk/pypy/module/imp/interp_imp.py (contents, props changed) pypy/trunk/pypy/module/imp/test/test_app.py (contents, props changed) pypy/trunk/pypy/module/oracle/interp_lob.py (contents, props changed) pypy/trunk/pypy/module/oracle/interp_object.py (contents, props changed) pypy/trunk/pypy/module/oracle/interp_pool.py (contents, props changed) pypy/trunk/pypy/module/oracle/test/test_cursorvar.py (contents, props changed) pypy/trunk/pypy/module/oracle/test/test_lobvar.py (contents, props changed) pypy/trunk/pypy/module/oracle/test/test_objectvar.py (contents, props changed) pypy/trunk/pypy/translator/benchmark/jitbench.py (props changed) Log: set svn:eol-style Modified: pypy/trunk/pypy/doc/config/objspace.usemodules.imp.txt ============================================================================== --- pypy/trunk/pypy/doc/config/objspace.usemodules.imp.txt (original) +++ pypy/trunk/pypy/doc/config/objspace.usemodules.imp.txt Tue Mar 9 15:46:14 2010 @@ -1,2 +1,2 @@ -Use the 'imp' module. -This module is included by default. +Use the 'imp' module. +This module is included by default. Modified: pypy/trunk/pypy/doc/discussion/improve-rpython.txt ============================================================================== --- pypy/trunk/pypy/doc/discussion/improve-rpython.txt (original) +++ pypy/trunk/pypy/doc/discussion/improve-rpython.txt Tue Mar 9 15:46:14 2010 @@ -1,93 +1,93 @@ -Possible improvements of the rpython language -============================================= - -Improve the interpreter API ---------------------------- - -- Rationalize the modules, and the names, of the differents functions needed to - implement a pypy module. A typical rpython file is likely to contain many - `import` statements:: - - from pypy.interpreter.baseobjspace import Wrappable - from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped - from pypy.interpreter.argument import Arguments - from pypy.interpreter.typedef import TypeDef, GetSetProperty - from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w - from pypy.interpreter.gateway import interp2app - from pypy.interpreter.error import OperationError - from pypy.rpython.lltypesystem import rffi, lltype - -- A more direct declarative way to write Typedef:: - - class W_Socket(Wrappable): - _typedef_name_ = 'socket' - _typedef_base_ = W_EventualBaseClass - - @interp2app_method("connect", ['self', ObjSpace, W_Root]) - def connect_w(self, space, w_addr): - ... - -- Support for metaclasses written in rpython. For a sample, see the skipped test - `pypy.objspace.std.test.TestTypeObject.test_metaclass_typedef` - -RPython language ----------------- - -- Arithmetic with unsigned integer, and between integer of different signedness, - when this is not ambiguous. At least, comparison and assignement with - constants should be allowed. - -- Allocate variables on the stack, and pass their address ("by reference") to - llexternal functions. For a typical usage, see - `pypy.rlib.rsocket.RSocket.getsockopt_int`. - -- Support context managers and the `with` statement. This could be a workaround - before the previous point is available. - -Extensible type system for llexternal -------------------------------------- - -llexternal allows the description of a C function, and conveys the same -information about the arguments as a C header. But this is often not enough. -For example, a parameter of type `int*` is converted to -`rffi.CArrayPtr(rffi.INT)`, but this information is not enough to use the -function. The parameter could be an array of int, a reference to a single value, -for input or output... - -A "type system" could hold this additional information, and automatically -generate some conversion code to ease the usage of the function from -rpython. For example:: - - # double frexp(double x, int *exp); - frexp = llexternal("frexp", [rffi.DOUBLE, OutPtr(rffi.int)], rffi.DOUBLE) - -`OutPtr` indicates that the parameter is output-only, which need not to be -initialized, and which *value* is returned to the caller. In rpython the call -becomes:: - - fraction, exponent = frexp(value) - -Also, we could imagine that one item in the llexternal argument list corresponds -to two parameters in C. Here, OutCharBufferN indicates that the caller will pass -a rpython string; the framework will pass buffer and length to the function:: - - # ssize_t write(int fd, const void *buf, size_t count); - write = llexternal("write", [rffi.INT, CharBufferAndSize], rffi.SSIZE_T) - -The rpython code that calls this function is very simple:: - - written = write(fd, data) - -compared with the present:: - - count = len(data) - buf = rffi.get_nonmovingbuffer(data) - try: - written = rffi.cast(lltype.Signed, os_write( - rffi.cast(rffi.INT, fd), - buf, rffi.cast(rffi.SIZE_T, count))) - finally: - rffi.free_nonmovingbuffer(data, buf) - -Typemaps are very useful for large APIs where the same conversions are needed in -many places. XXX example +Possible improvements of the rpython language +============================================= + +Improve the interpreter API +--------------------------- + +- Rationalize the modules, and the names, of the differents functions needed to + implement a pypy module. A typical rpython file is likely to contain many + `import` statements:: + + from pypy.interpreter.baseobjspace import Wrappable + from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + from pypy.interpreter.argument import Arguments + from pypy.interpreter.typedef import TypeDef, GetSetProperty + from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w + from pypy.interpreter.gateway import interp2app + from pypy.interpreter.error import OperationError + from pypy.rpython.lltypesystem import rffi, lltype + +- A more direct declarative way to write Typedef:: + + class W_Socket(Wrappable): + _typedef_name_ = 'socket' + _typedef_base_ = W_EventualBaseClass + + @interp2app_method("connect", ['self', ObjSpace, W_Root]) + def connect_w(self, space, w_addr): + ... + +- Support for metaclasses written in rpython. For a sample, see the skipped test + `pypy.objspace.std.test.TestTypeObject.test_metaclass_typedef` + +RPython language +---------------- + +- Arithmetic with unsigned integer, and between integer of different signedness, + when this is not ambiguous. At least, comparison and assignement with + constants should be allowed. + +- Allocate variables on the stack, and pass their address ("by reference") to + llexternal functions. For a typical usage, see + `pypy.rlib.rsocket.RSocket.getsockopt_int`. + +- Support context managers and the `with` statement. This could be a workaround + before the previous point is available. + +Extensible type system for llexternal +------------------------------------- + +llexternal allows the description of a C function, and conveys the same +information about the arguments as a C header. But this is often not enough. +For example, a parameter of type `int*` is converted to +`rffi.CArrayPtr(rffi.INT)`, but this information is not enough to use the +function. The parameter could be an array of int, a reference to a single value, +for input or output... + +A "type system" could hold this additional information, and automatically +generate some conversion code to ease the usage of the function from +rpython. For example:: + + # double frexp(double x, int *exp); + frexp = llexternal("frexp", [rffi.DOUBLE, OutPtr(rffi.int)], rffi.DOUBLE) + +`OutPtr` indicates that the parameter is output-only, which need not to be +initialized, and which *value* is returned to the caller. In rpython the call +becomes:: + + fraction, exponent = frexp(value) + +Also, we could imagine that one item in the llexternal argument list corresponds +to two parameters in C. Here, OutCharBufferN indicates that the caller will pass +a rpython string; the framework will pass buffer and length to the function:: + + # ssize_t write(int fd, const void *buf, size_t count); + write = llexternal("write", [rffi.INT, CharBufferAndSize], rffi.SSIZE_T) + +The rpython code that calls this function is very simple:: + + written = write(fd, data) + +compared with the present:: + + count = len(data) + buf = rffi.get_nonmovingbuffer(data) + try: + written = rffi.cast(lltype.Signed, os_write( + rffi.cast(rffi.INT, fd), + buf, rffi.cast(rffi.SIZE_T, count))) + finally: + rffi.free_nonmovingbuffer(data, buf) + +Typemaps are very useful for large APIs where the same conversions are needed in +many places. XXX example Modified: pypy/trunk/pypy/module/_collections/__init__.py ============================================================================== --- pypy/trunk/pypy/module/_collections/__init__.py (original) +++ pypy/trunk/pypy/module/_collections/__init__.py Tue Mar 9 15:46:14 2010 @@ -1,11 +1,11 @@ -import py - -from pypy.interpreter.mixedmodule import MixedModule - -class Module(MixedModule): - appleveldefs = {} - - interpleveldefs = { - 'identity_dict' : 'interp_collection.W_IdentityDict', - } - +import py + +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + appleveldefs = {} + + interpleveldefs = { + 'identity_dict' : 'interp_collection.W_IdentityDict', + } + Modified: pypy/trunk/pypy/module/_collections/interp_collection.py ============================================================================== --- pypy/trunk/pypy/module/_collections/interp_collection.py (original) +++ pypy/trunk/pypy/module/_collections/interp_collection.py Tue Mar 9 15:46:14 2010 @@ -1,68 +1,68 @@ -from pypy.interpreter.error import OperationError -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, interp2app -from pypy.interpreter.gateway import Arguments, unwrap_spec -from pypy.interpreter.baseobjspace import Wrappable - -class W_IdentityDict(Wrappable): - def __init__(self, space): - self.dict = {} - __init__.unwrap_spec = ['self', ObjSpace] - - @unwrap_spec(ObjSpace, W_Root) - def descr_new(space, w_subtype): - self = space.allocate_instance(W_IdentityDict, w_subtype) - W_IdentityDict.__init__(self, space) - return space.wrap(self) - - @unwrap_spec('self', ObjSpace) - def descr_len(self, space): - return space.wrap(len(self.dict)) - - @unwrap_spec('self', ObjSpace, W_Root) - def descr_contains(self, space, w_key): - return space.wrap(w_key in self.dict) - - @unwrap_spec('self', ObjSpace, W_Root, W_Root) - def descr_setitem(self, space, w_key, w_value): - self.dict[w_key] = w_value - - @unwrap_spec('self', ObjSpace, W_Root) - def descr_getitem(self, space, w_key): - try: - return self.dict[w_key] - except KeyError: - raise OperationError(space.w_KeyError, w_key) - - @unwrap_spec('self', ObjSpace, W_Root, W_Root) - def get(self, space, w_key, w_default=None): - return self.dict.get(w_key, w_default) - - @unwrap_spec('self', ObjSpace) - def keys(self, space): - return space.newlist(self.dict.keys()) - - @unwrap_spec('self', ObjSpace) - def values(self, space): - return space.newlist(self.dict.values()) - - @unwrap_spec('self', ObjSpace) - def clear(self, space): - self.dict.clear() - -W_IdentityDict.typedef = TypeDef("identity_dict", - __doc__="""\ -A dictionary that considers keys by object identity. -Distinct objects that compare equal will have separate entries. -All objects can be used as keys, even non-hashable ones. -""", - __new__ = interp2app(W_IdentityDict.descr_new.im_func), - __len__ = interp2app(W_IdentityDict.descr_len), - __contains__ = interp2app(W_IdentityDict.descr_contains), - __setitem__ = interp2app(W_IdentityDict.descr_setitem), - __getitem__ = interp2app(W_IdentityDict.descr_getitem), - get = interp2app(W_IdentityDict.get), - keys = interp2app(W_IdentityDict.keys), - values = interp2app(W_IdentityDict.values), - clear = interp2app(W_IdentityDict.clear), -) +from pypy.interpreter.error import OperationError +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped, interp2app +from pypy.interpreter.gateway import Arguments, unwrap_spec +from pypy.interpreter.baseobjspace import Wrappable + +class W_IdentityDict(Wrappable): + def __init__(self, space): + self.dict = {} + __init__.unwrap_spec = ['self', ObjSpace] + + @unwrap_spec(ObjSpace, W_Root) + def descr_new(space, w_subtype): + self = space.allocate_instance(W_IdentityDict, w_subtype) + W_IdentityDict.__init__(self, space) + return space.wrap(self) + + @unwrap_spec('self', ObjSpace) + def descr_len(self, space): + return space.wrap(len(self.dict)) + + @unwrap_spec('self', ObjSpace, W_Root) + def descr_contains(self, space, w_key): + return space.wrap(w_key in self.dict) + + @unwrap_spec('self', ObjSpace, W_Root, W_Root) + def descr_setitem(self, space, w_key, w_value): + self.dict[w_key] = w_value + + @unwrap_spec('self', ObjSpace, W_Root) + def descr_getitem(self, space, w_key): + try: + return self.dict[w_key] + except KeyError: + raise OperationError(space.w_KeyError, w_key) + + @unwrap_spec('self', ObjSpace, W_Root, W_Root) + def get(self, space, w_key, w_default=None): + return self.dict.get(w_key, w_default) + + @unwrap_spec('self', ObjSpace) + def keys(self, space): + return space.newlist(self.dict.keys()) + + @unwrap_spec('self', ObjSpace) + def values(self, space): + return space.newlist(self.dict.values()) + + @unwrap_spec('self', ObjSpace) + def clear(self, space): + self.dict.clear() + +W_IdentityDict.typedef = TypeDef("identity_dict", + __doc__="""\ +A dictionary that considers keys by object identity. +Distinct objects that compare equal will have separate entries. +All objects can be used as keys, even non-hashable ones. +""", + __new__ = interp2app(W_IdentityDict.descr_new.im_func), + __len__ = interp2app(W_IdentityDict.descr_len), + __contains__ = interp2app(W_IdentityDict.descr_contains), + __setitem__ = interp2app(W_IdentityDict.descr_setitem), + __getitem__ = interp2app(W_IdentityDict.descr_getitem), + get = interp2app(W_IdentityDict.get), + keys = interp2app(W_IdentityDict.keys), + values = interp2app(W_IdentityDict.values), + clear = interp2app(W_IdentityDict.clear), +) Modified: pypy/trunk/pypy/module/_collections/test/test_collection.py ============================================================================== --- pypy/trunk/pypy/module/_collections/test/test_collection.py (original) +++ pypy/trunk/pypy/module/_collections/test/test_collection.py Tue Mar 9 15:46:14 2010 @@ -1,61 +1,61 @@ -import py -from pypy.conftest import gettestobjspace - -class AppTestIdentityDict: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_collections']) - - def test_numbers(self): - from _collections import identity_dict - d = identity_dict() - d[0] = 1 - d[0.0] = 2 - d[long(0)] = 3 - - assert d - assert len(d) == 3 - d.clear() - assert not d - - def test_get(self): - from _collections import identity_dict - d = identity_dict() - d[None] = 1 - - assert d.get(None, 42) == 1 - assert d.get(None) == 1 - assert d.get(1) is None - assert d.get(1, 42) == 42 - - def test_unhashable(self): - from _collections import identity_dict - - d = identity_dict() - d[[]] = 1 - d[[]] = 2 - a = [] - d[a] = 3 - assert len(d) == 3 - d[a] = 4 - assert len(d) == 3 - assert d[a] == 4 - - raises(KeyError, d.__getitem__, []) - - def test_keys(self): - from _collections import identity_dict - d = identity_dict() - d[[]] = 1 - d[[]] = 2 - d[[]] = 3 - - assert d.keys() == [[], [], []] - assert sorted(d.values()) == [1, 2, 3] - - def test_in(self): - from _collections import identity_dict - d = identity_dict() - d[None] = 1 - - assert None in d - assert [] not in d +import py +from pypy.conftest import gettestobjspace + +class AppTestIdentityDict: + def setup_class(cls): + cls.space = gettestobjspace(usemodules=['_collections']) + + def test_numbers(self): + from _collections import identity_dict + d = identity_dict() + d[0] = 1 + d[0.0] = 2 + d[long(0)] = 3 + + assert d + assert len(d) == 3 + d.clear() + assert not d + + def test_get(self): + from _collections import identity_dict + d = identity_dict() + d[None] = 1 + + assert d.get(None, 42) == 1 + assert d.get(None) == 1 + assert d.get(1) is None + assert d.get(1, 42) == 42 + + def test_unhashable(self): + from _collections import identity_dict + + d = identity_dict() + d[[]] = 1 + d[[]] = 2 + a = [] + d[a] = 3 + assert len(d) == 3 + d[a] = 4 + assert len(d) == 3 + assert d[a] == 4 + + raises(KeyError, d.__getitem__, []) + + def test_keys(self): + from _collections import identity_dict + d = identity_dict() + d[[]] = 1 + d[[]] = 2 + d[[]] = 3 + + assert d.keys() == [[], [], []] + assert sorted(d.values()) == [1, 2, 3] + + def test_in(self): + from _collections import identity_dict + d = identity_dict() + d[None] = 1 + + assert None in d + assert [] not in d Modified: pypy/trunk/pypy/module/imp/interp_imp.py ============================================================================== --- pypy/trunk/pypy/module/imp/interp_imp.py (original) +++ pypy/trunk/pypy/module/imp/interp_imp.py Tue Mar 9 15:46:14 2010 @@ -1,154 +1,154 @@ -from pypy.module.imp import importing -from pypy.module._file.interp_file import W_File -from pypy.rlib import streamio -from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.module import Module -from pypy.interpreter.gateway import NoneNotWrapped -import struct - -def get_suffixes(space): - w = space.wrap - return space.newlist([ - space.newtuple([w('.py'), w('U'), w(importing.PY_SOURCE)]), - space.newtuple([w('.pyc'), w('rb'), w(importing.PY_COMPILED)]), - ]) - -def get_magic(space): - x = importing.get_pyc_magic(space) - a = x & 0xff - x >>= 8 - b = x & 0xff - x >>= 8 - c = x & 0xff - x >>= 8 - d = x & 0xff - return space.wrap(chr(a) + chr(b) + chr(c) + chr(d)) - -def get_file(space, w_file, filename, filemode): - if w_file is None or space.is_w(w_file, space.w_None): - return streamio.open_file_as_stream(filename, filemode) - else: - return space.interp_w(W_File, w_file).stream - -def find_module(space, w_name, w_path=None): - name = space.str_w(w_name) - if space.is_w(w_path, space.w_None): - w_path = None - - find_info = importing.find_module( - space, name, w_name, name, w_path, use_loader=False) - if not find_info: - raise operationerrfmt( - space.w_ImportError, - "No module named %s", name) - - w_filename = space.wrap(find_info.filename) - stream = find_info.stream - - if stream is not None: - fileobj = W_File(space) - fileobj.fdopenstream( - stream, stream.try_to_find_file_descriptor(), - find_info.filemode, w_filename) - w_fileobj = space.wrap(fileobj) - else: - w_fileobj = space.w_None - w_import_info = space.newtuple( - [space.wrap(find_info.suffix), - space.wrap(find_info.filemode), - space.wrap(find_info.modtype)]) - return space.newtuple([w_fileobj, w_filename, w_import_info]) - -def load_module(space, w_name, w_file, w_filename, w_info): - w_suffix, w_filemode, w_modtype = space.unpackiterable(w_info) - - filename = space.str_w(w_filename) - filemode = space.str_w(w_filemode) - if space.is_w(w_file, space.w_None): - stream = None - else: - stream = get_file(space, w_file, filename, filemode) - - find_info = importing.FindInfo( - space.int_w(w_modtype), - filename, - stream, - space.str_w(w_suffix), - filemode) - return importing.load_module( - space, w_name, find_info) - -def load_source(space, w_modulename, w_filename, w_file=None): - filename = space.str_w(w_filename) - - stream = get_file(space, w_file, filename, 'U') - - w_mod = space.wrap(Module(space, w_modulename)) - importing._prepare_module(space, w_mod, filename, None) - - importing.load_source_module( - space, w_modulename, w_mod, filename, stream.readall()) - if space.is_w(w_file, space.w_None): - stream.close() - return w_mod - -def load_compiled(space, w_modulename, w_filename, w_file=None): - filename = space.str_w(w_filename) - - stream = get_file(space, w_file, filename, 'rb') - - w_mod = space.wrap(Module(space, w_modulename)) - importing._prepare_module(space, w_mod, filename, None) - - magic = importing._r_long(stream) - timestamp = importing._r_long(stream) - - importing.load_compiled_module( - space, w_modulename, w_mod, filename, magic, timestamp, - stream.readall()) - if space.is_w(w_file, space.w_None): - stream.close() - return w_mod - -def new_module(space, w_name): - return space.wrap(Module(space, w_name)) - -def init_builtin(space, w_name): - name = space.str_w(w_name) - if name not in space.builtin_modules: - return - if space.finditem(space.sys.get('modules'), w_name) is not None: - raise OperationError( - space.w_ImportError, - space.wrap("cannot initialize a built-in module twice in PyPy")) - return space.getbuiltinmodule(name) - -def init_frozen(space, w_name): - return None - -def is_builtin(space, w_name): - name = space.str_w(w_name) - if name not in space.builtin_modules: - return space.wrap(0) - if space.finditem(space.sys.get('modules'), w_name) is not None: - return space.wrap(-1) # cannot be initialized again - return space.wrap(1) - -def is_frozen(space, w_name): - return space.w_False - -#__________________________________________________________________ - -def lock_held(space): - if space.config.objspace.usemodules.thread: - return space.wrap(importing.getimportlock(space).lock_held()) - else: - return space.w_False - -def acquire_lock(space): - if space.config.objspace.usemodules.thread: - importing.getimportlock(space).acquire_lock() - -def release_lock(space): - if space.config.objspace.usemodules.thread: - importing.getimportlock(space).release_lock() +from pypy.module.imp import importing +from pypy.module._file.interp_file import W_File +from pypy.rlib import streamio +from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.module import Module +from pypy.interpreter.gateway import NoneNotWrapped +import struct + +def get_suffixes(space): + w = space.wrap + return space.newlist([ + space.newtuple([w('.py'), w('U'), w(importing.PY_SOURCE)]), + space.newtuple([w('.pyc'), w('rb'), w(importing.PY_COMPILED)]), + ]) + +def get_magic(space): + x = importing.get_pyc_magic(space) + a = x & 0xff + x >>= 8 + b = x & 0xff + x >>= 8 + c = x & 0xff + x >>= 8 + d = x & 0xff + return space.wrap(chr(a) + chr(b) + chr(c) + chr(d)) + +def get_file(space, w_file, filename, filemode): + if w_file is None or space.is_w(w_file, space.w_None): + return streamio.open_file_as_stream(filename, filemode) + else: + return space.interp_w(W_File, w_file).stream + +def find_module(space, w_name, w_path=None): + name = space.str_w(w_name) + if space.is_w(w_path, space.w_None): + w_path = None + + find_info = importing.find_module( + space, name, w_name, name, w_path, use_loader=False) + if not find_info: + raise operationerrfmt( + space.w_ImportError, + "No module named %s", name) + + w_filename = space.wrap(find_info.filename) + stream = find_info.stream + + if stream is not None: + fileobj = W_File(space) + fileobj.fdopenstream( + stream, stream.try_to_find_file_descriptor(), + find_info.filemode, w_filename) + w_fileobj = space.wrap(fileobj) + else: + w_fileobj = space.w_None + w_import_info = space.newtuple( + [space.wrap(find_info.suffix), + space.wrap(find_info.filemode), + space.wrap(find_info.modtype)]) + return space.newtuple([w_fileobj, w_filename, w_import_info]) + +def load_module(space, w_name, w_file, w_filename, w_info): + w_suffix, w_filemode, w_modtype = space.unpackiterable(w_info) + + filename = space.str_w(w_filename) + filemode = space.str_w(w_filemode) + if space.is_w(w_file, space.w_None): + stream = None + else: + stream = get_file(space, w_file, filename, filemode) + + find_info = importing.FindInfo( + space.int_w(w_modtype), + filename, + stream, + space.str_w(w_suffix), + filemode) + return importing.load_module( + space, w_name, find_info) + +def load_source(space, w_modulename, w_filename, w_file=None): + filename = space.str_w(w_filename) + + stream = get_file(space, w_file, filename, 'U') + + w_mod = space.wrap(Module(space, w_modulename)) + importing._prepare_module(space, w_mod, filename, None) + + importing.load_source_module( + space, w_modulename, w_mod, filename, stream.readall()) + if space.is_w(w_file, space.w_None): + stream.close() + return w_mod + +def load_compiled(space, w_modulename, w_filename, w_file=None): + filename = space.str_w(w_filename) + + stream = get_file(space, w_file, filename, 'rb') + + w_mod = space.wrap(Module(space, w_modulename)) + importing._prepare_module(space, w_mod, filename, None) + + magic = importing._r_long(stream) + timestamp = importing._r_long(stream) + + importing.load_compiled_module( + space, w_modulename, w_mod, filename, magic, timestamp, + stream.readall()) + if space.is_w(w_file, space.w_None): + stream.close() + return w_mod + +def new_module(space, w_name): + return space.wrap(Module(space, w_name)) + +def init_builtin(space, w_name): + name = space.str_w(w_name) + if name not in space.builtin_modules: + return + if space.finditem(space.sys.get('modules'), w_name) is not None: + raise OperationError( + space.w_ImportError, + space.wrap("cannot initialize a built-in module twice in PyPy")) + return space.getbuiltinmodule(name) + +def init_frozen(space, w_name): + return None + +def is_builtin(space, w_name): + name = space.str_w(w_name) + if name not in space.builtin_modules: + return space.wrap(0) + if space.finditem(space.sys.get('modules'), w_name) is not None: + return space.wrap(-1) # cannot be initialized again + return space.wrap(1) + +def is_frozen(space, w_name): + return space.w_False + +#__________________________________________________________________ + +def lock_held(space): + if space.config.objspace.usemodules.thread: + return space.wrap(importing.getimportlock(space).lock_held()) + else: + return space.w_False + +def acquire_lock(space): + if space.config.objspace.usemodules.thread: + importing.getimportlock(space).acquire_lock() + +def release_lock(space): + if space.config.objspace.usemodules.thread: + importing.getimportlock(space).release_lock() Modified: pypy/trunk/pypy/module/imp/test/test_app.py ============================================================================== --- pypy/trunk/pypy/module/imp/test/test_app.py (original) +++ pypy/trunk/pypy/module/imp/test/test_app.py Tue Mar 9 15:46:14 2010 @@ -1,112 +1,112 @@ -MARKER = 42 - -class AppTestImpModule: - def setup_class(cls): - cls.w_imp = cls.space.getbuiltinmodule('imp') - - cls.w__py_file = cls.space.appexec( - [cls.space.wrap(__file__)], r"""(__file__): - def _py_file(): - fn = __file__ - if fn.lower().endswith('c') or fn.lower().endswith('o'): - fn = fn[:-1] - assert fn.lower().endswith('.py') - return fn - return _py_file""") - - cls.w__pyc_file = cls.space.appexec([], r"""(): - def _pyc_file(): - import marshal, imp - co = compile("marker=42", "x.py", "exec") - f = open('@TEST.pyc', 'wb') - f.write(imp.get_magic()) - f.write('\x00\x00\x00\x00') - marshal.dump(co, f) - f.close() - return '@TEST.pyc' - return _pyc_file""") - - - - def test_find_module(self): - import os - file, pathname, description = self.imp.find_module('StringIO') - assert file is not None - file.close() - assert os.path.exists(pathname) - pathname = pathname.lower() - assert pathname.endswith('.py') # even if .pyc is up-to-date - assert description in self.imp.get_suffixes() - - - def test_suffixes(self): - for suffix, mode, type in self.imp.get_suffixes(): - if mode == self.imp.PY_SOURCE: - assert suffix == '.py' - assert type == 'r' - elif mode == self.imp.PY_COMPILED: - assert suffix in ('.pyc', '.pyo') - assert type == 'rb' - - - def test_obscure_functions(self): - mod = self.imp.new_module('hi') - assert mod.__name__ == 'hi' - mod = self.imp.init_builtin('hello.world.this.is.never.a.builtin.module.name') - assert mod is None - mod = self.imp.init_frozen('hello.world.this.is.never.a.frozen.module.name') - assert mod is None - assert self.imp.is_builtin('sys') - assert not self.imp.is_builtin('hello.world.this.is.never.a.builtin.module.name') - assert not self.imp.is_frozen('hello.world.this.is.never.a.frozen.module.name') - - - def test_load_module_py(self): - fn = self._py_file() - descr = ('.py', 'U', self.imp.PY_SOURCE) - f = open(fn, 'U') - mod = self.imp.load_module('test_imp_extra_AUTO1', f, fn, descr) - f.close() - assert mod.MARKER == 42 - import test_imp_extra_AUTO1 - assert mod is test_imp_extra_AUTO1 - - def test_load_module_pyc(self): - fn = self._pyc_file() - try: - descr = ('.pyc', 'rb', self.imp.PY_COMPILED) - f = open(fn, 'rb') - mod = self.imp.load_module('test_imp_extra_AUTO2', f, fn, descr) - f.close() - assert mod.marker == 42 - import test_imp_extra_AUTO2 - assert mod is test_imp_extra_AUTO2 - finally: - os.unlink(fn) - - def test_load_source(self): - fn = self._py_file() - mod = self.imp.load_source('test_imp_extra_AUTO3', fn) - assert mod.MARKER == 42 - import test_imp_extra_AUTO3 - assert mod is test_imp_extra_AUTO3 - - def test_load_module_pyc(self): - import os - fn = self._pyc_file() - try: - mod = self.imp.load_compiled('test_imp_extra_AUTO4', fn) - assert mod.marker == 42 - import test_imp_extra_AUTO4 - assert mod is test_imp_extra_AUTO4 - finally: - os.unlink(fn) - - def test_load_broken_pyc(self): - fn = self._py_file() - try: - self.imp.load_compiled('test_imp_extra_AUTO5', fn) - except ImportError: - pass - else: - raise Exception("expected an ImportError") +MARKER = 42 + +class AppTestImpModule: + def setup_class(cls): + cls.w_imp = cls.space.getbuiltinmodule('imp') + + cls.w__py_file = cls.space.appexec( + [cls.space.wrap(__file__)], r"""(__file__): + def _py_file(): + fn = __file__ + if fn.lower().endswith('c') or fn.lower().endswith('o'): + fn = fn[:-1] + assert fn.lower().endswith('.py') + return fn + return _py_file""") + + cls.w__pyc_file = cls.space.appexec([], r"""(): + def _pyc_file(): + import marshal, imp + co = compile("marker=42", "x.py", "exec") + f = open('@TEST.pyc', 'wb') + f.write(imp.get_magic()) + f.write('\x00\x00\x00\x00') + marshal.dump(co, f) + f.close() + return '@TEST.pyc' + return _pyc_file""") + + + + def test_find_module(self): + import os + file, pathname, description = self.imp.find_module('StringIO') + assert file is not None + file.close() + assert os.path.exists(pathname) + pathname = pathname.lower() + assert pathname.endswith('.py') # even if .pyc is up-to-date + assert description in self.imp.get_suffixes() + + + def test_suffixes(self): + for suffix, mode, type in self.imp.get_suffixes(): + if mode == self.imp.PY_SOURCE: + assert suffix == '.py' + assert type == 'r' + elif mode == self.imp.PY_COMPILED: + assert suffix in ('.pyc', '.pyo') + assert type == 'rb' + + + def test_obscure_functions(self): + mod = self.imp.new_module('hi') + assert mod.__name__ == 'hi' + mod = self.imp.init_builtin('hello.world.this.is.never.a.builtin.module.name') + assert mod is None + mod = self.imp.init_frozen('hello.world.this.is.never.a.frozen.module.name') + assert mod is None + assert self.imp.is_builtin('sys') + assert not self.imp.is_builtin('hello.world.this.is.never.a.builtin.module.name') + assert not self.imp.is_frozen('hello.world.this.is.never.a.frozen.module.name') + + + def test_load_module_py(self): + fn = self._py_file() + descr = ('.py', 'U', self.imp.PY_SOURCE) + f = open(fn, 'U') + mod = self.imp.load_module('test_imp_extra_AUTO1', f, fn, descr) + f.close() + assert mod.MARKER == 42 + import test_imp_extra_AUTO1 + assert mod is test_imp_extra_AUTO1 + + def test_load_module_pyc(self): + fn = self._pyc_file() + try: + descr = ('.pyc', 'rb', self.imp.PY_COMPILED) + f = open(fn, 'rb') + mod = self.imp.load_module('test_imp_extra_AUTO2', f, fn, descr) + f.close() + assert mod.marker == 42 + import test_imp_extra_AUTO2 + assert mod is test_imp_extra_AUTO2 + finally: + os.unlink(fn) + + def test_load_source(self): + fn = self._py_file() + mod = self.imp.load_source('test_imp_extra_AUTO3', fn) + assert mod.MARKER == 42 + import test_imp_extra_AUTO3 + assert mod is test_imp_extra_AUTO3 + + def test_load_module_pyc(self): + import os + fn = self._pyc_file() + try: + mod = self.imp.load_compiled('test_imp_extra_AUTO4', fn) + assert mod.marker == 42 + import test_imp_extra_AUTO4 + assert mod is test_imp_extra_AUTO4 + finally: + os.unlink(fn) + + def test_load_broken_pyc(self): + fn = self._py_file() + try: + self.imp.load_compiled('test_imp_extra_AUTO5', fn) + except ImportError: + pass + else: + raise Exception("expected an ImportError") Modified: pypy/trunk/pypy/module/oracle/interp_lob.py ============================================================================== --- pypy/trunk/pypy/module/oracle/interp_lob.py (original) +++ pypy/trunk/pypy/module/oracle/interp_lob.py Tue Mar 9 15:46:14 2010 @@ -1,47 +1,47 @@ -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import ObjSpace -from pypy.interpreter.gateway import interp2app -from pypy.interpreter.error import OperationError - -from pypy.module.oracle.interp_error import get - -class W_ExternalLob(Wrappable): - def __init__(self, var, pos): - self.lobVar = var - self.pos = pos - self.internalFetchNum = var.internalFetchNum - - def _verify(self, space): - if self.internalFetchNum != self.lobVar.internalFetchNum: - raise OperationError( - get(space).w_ProgrammingError, - space.wrap( - "LOB variable no longer valid after subsequent fetch")) - - def read(self, space, offset=-1, amount=-1): - self._verify(space) - return self.lobVar.read(space, self.pos, offset, amount) - read.unwrap_spec = ['self', ObjSpace, int, int] - - def size(self, space): - self._verify(space) - return space.wrap(self.lobVar.getLength(space, self.pos)) - size.unwrap_spec = ['self', ObjSpace] - - def trim(self, space, newSize=0): - self._verify(space) - self.lobVar.trim(space, self.pos, newSize) - trim.unwrap_spec = ['self', ObjSpace, int] - - def desc_str(self, space): - return self.read(space, offset=1, amount=-1) - desc_str.unwrap_spec = ['self', ObjSpace] - -W_ExternalLob.typedef = TypeDef( - 'ExternalLob', - read = interp2app(W_ExternalLob.read), - size = interp2app(W_ExternalLob.size), - trim = interp2app(W_ExternalLob.trim), - __str__ = interp2app(W_ExternalLob.desc_str), - ) +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import ObjSpace +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.error import OperationError + +from pypy.module.oracle.interp_error import get + +class W_ExternalLob(Wrappable): + def __init__(self, var, pos): + self.lobVar = var + self.pos = pos + self.internalFetchNum = var.internalFetchNum + + def _verify(self, space): + if self.internalFetchNum != self.lobVar.internalFetchNum: + raise OperationError( + get(space).w_ProgrammingError, + space.wrap( + "LOB variable no longer valid after subsequent fetch")) + + def read(self, space, offset=-1, amount=-1): + self._verify(space) + return self.lobVar.read(space, self.pos, offset, amount) + read.unwrap_spec = ['self', ObjSpace, int, int] + + def size(self, space): + self._verify(space) + return space.wrap(self.lobVar.getLength(space, self.pos)) + size.unwrap_spec = ['self', ObjSpace] + + def trim(self, space, newSize=0): + self._verify(space) + self.lobVar.trim(space, self.pos, newSize) + trim.unwrap_spec = ['self', ObjSpace, int] + + def desc_str(self, space): + return self.read(space, offset=1, amount=-1) + desc_str.unwrap_spec = ['self', ObjSpace] + +W_ExternalLob.typedef = TypeDef( + 'ExternalLob', + read = interp2app(W_ExternalLob.read), + size = interp2app(W_ExternalLob.size), + trim = interp2app(W_ExternalLob.trim), + __str__ = interp2app(W_ExternalLob.desc_str), + ) Modified: pypy/trunk/pypy/module/oracle/interp_object.py ============================================================================== --- pypy/trunk/pypy/module/oracle/interp_object.py (original) +++ pypy/trunk/pypy/module/oracle/interp_object.py Tue Mar 9 15:46:14 2010 @@ -1,516 +1,516 @@ -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.typedef import interp_attrproperty -from pypy.interpreter.gateway import ObjSpace -from pypy.interpreter.gateway import interp2app -from pypy.interpreter.error import OperationError -from pypy.rpython.lltypesystem import rffi, lltype - -from pypy.module.oracle import roci, config, transform -from pypy.module.oracle.interp_error import get - -class W_ObjectType(Wrappable): - def __init__(self, connection, param): - self.tdo = lltype.nullptr(roci.dvoidp.TO) - self.environment = connection.environment - self.isCollection = False - self.initialize(connection, param) - - def __del__(self): - if self.tdo: - roci.OCIObjectUnpin( - self.environment.handle, - self.environment.errorHandle, - self.tdo) - - def initialize(self, connection, param): - nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, - flavor='raw') - lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, - flavor='raw') - try: - # determine the schema of the type - status = roci.OCIAttrGet( - param, roci.OCI_HTYPE_DESCRIBE, - rffi.cast(roci.dvoidp, nameptr), - lenptr, - roci.OCI_ATTR_SCHEMA_NAME, - self.environment.errorHandle) - self.environment.checkForError( - status, - "ObjectType_Initialize(): get schema name") - self.schema = rffi.charpsize2str(nameptr[0], lenptr[0]) - - # determine the name of the type - status = roci.OCIAttrGet( - param, roci.OCI_HTYPE_DESCRIBE, - rffi.cast(roci.dvoidp, nameptr), - lenptr, - roci.OCI_ATTR_TYPE_NAME, - self.environment.errorHandle) - self.environment.checkForError( - status, - "ObjectType_Initialize(): get schema name") - self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) - finally: - lltype.free(nameptr, flavor='raw') - lltype.free(lenptr, flavor='raw') - - # retrieve TDO (type descriptor object) of the parameter - tdorefptr = lltype.malloc(rffi.CArrayPtr(roci.OCIRef).TO, 1, - flavor='raw') - try: - status = roci.OCIAttrGet( - param, roci.OCI_HTYPE_DESCRIBE, - rffi.cast(roci.dvoidp, tdorefptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_REF_TDO, - self.environment.errorHandle) - self.environment.checkForError( - status, - "ObjectType_Initialize(): get TDO reference") - tdoref = tdorefptr[0] - finally: - lltype.free(tdorefptr, flavor='raw') - - tdoptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, - flavor='raw') - try: - status = roci.OCIObjectPin( - self.environment.handle, - self.environment.errorHandle, - tdoref, - None, roci.OCI_PIN_ANY, - roci.OCI_DURATION_SESSION, roci.OCI_LOCK_NONE, - tdoptr) - self.environment.checkForError( - status, - "ObjectType_Initialize(): pin TDO reference") - self.tdo = tdoptr[0] - finally: - lltype.free(tdoptr, flavor='raw') - - # acquire a describe handle - handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIDescribe).TO, - 1, flavor='raw') - try: - status = roci.OCIHandleAlloc( - self.environment.handle, - handleptr, roci.OCI_HTYPE_DESCRIBE, 0, - lltype.nullptr(rffi.CArray(roci.dvoidp))) - self.environment.checkForError( - status, "ObjectType_Initialize(): allocate describe handle") - describeHandle = handleptr[0] - finally: - lltype.free(handleptr, flavor='raw') - - # describe the type - try: - self.describe(connection, describeHandle) - finally: - roci.OCIHandleFree(describeHandle, roci.OCI_HTYPE_DESCRIBE) - - def describe(self, connection, describeHandle): - "Describe the type and store information about it as needed" - - # describe the type - status = roci.OCIDescribeAny( - connection.handle, - self.environment.errorHandle, - self.tdo, 0, - roci.OCI_OTYPE_PTR, - roci.OCI_DEFAULT, - roci.OCI_PTYPE_TYPE, - describeHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): describe type") - - # get top level parameter descriptor - paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - describeHandle, roci.OCI_HTYPE_DESCRIBE, - rffi.cast(roci.dvoidp, paramptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_PARAM, - self.environment.errorHandle) - self.environment.checkForError( - status, - "ObjectType_Describe(): get top level parameter descriptor") - toplevelParam = paramptr[0] - finally: - lltype.free(paramptr, flavor='raw') - - # determine type of type - typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - toplevelParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, typecodeptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_TYPECODE, - self.environment.errorHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): get type code") - typeCode = rffi.cast(lltype.Signed, typecodeptr[0]) - finally: - lltype.free(typecodeptr, flavor='raw') - - # if a collection, need to determine the sub type - if typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION: - self.isCollection = 1 - - # determine type of collection - typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - toplevelParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, typecodeptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_TYPECODE, - self.environment.errorHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): get collection type code") - self.collectionTypeCode = typecodeptr[0] - finally: - lltype.free(typecodeptr, flavor='raw') - - # acquire collection parameter descriptor - paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - toplevelParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, paramptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_COLLECTION_ELEMENT, - self.environment.errorHandle) - self.environment.checkForError( - status, - "ObjectType_Describe(): get collection descriptor") - collectionParam = paramptr[0] - finally: - lltype.free(paramptr, flavor='raw') - - # determine type of element - typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - collectionParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, typecodeptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_TYPECODE, - self.environment.errorHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): get element type code") - self.elementTypeCode = rffi.cast(lltype.Signed, typecodeptr[0]) - finally: - lltype.free(typecodeptr, flavor='raw') - - # if element type is an object type get its type - if self.elementTypeCode == roci.OCI_TYPECODE_OBJECT: - self.elementType = W_ObjectType(connection, collectionParam) - else: - self.elementType = None - - # determine the number of attributes - numptr = lltype.malloc(roci.Ptr(roci.ub2).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - toplevelParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, numptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_NUM_TYPE_ATTRS, - self.environment.errorHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): get number of attributes") - numAttributes = numptr[0] - finally: - lltype.free(numptr, flavor='raw') - - # allocate the attribute list and dictionary - self.attributes = [] - self.attributesByName = {} - - # acquire the list parameter descriptor - listptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - toplevelParam, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, listptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_LIST_TYPE_ATTRS, - self.environment.errorHandle) - self.environment.checkForError( - status, "ObjectType_Describe(): get list parameter descriptor") - attributeListParam = listptr[0] - finally: - lltype.free(listptr, flavor='raw') - - # create attribute information for each attribute - for i in range(numAttributes): - paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, - 1, flavor='raw') - try: - status = roci.OCIParamGet( - attributeListParam, roci.OCI_DTYPE_PARAM, - self.environment.errorHandle, - paramptr, i + 1) - self.environment.checkForError( - status, - "ObjectType_Describe(): get attribute param descriptor") - attribute = W_ObjectAttribute(connection, paramptr[0]) - finally: - lltype.free(paramptr, flavor='raw') - - self.attributes.append(attribute) - self.attributesByName[attribute.name] = attribute - - def get_attributes(space, self): - return space.newlist([space.wrap(attr) for attr in self.attributes]) - -W_ObjectType.typedef = TypeDef( - 'ObjectType', - schema = interp_attrproperty('schema', W_ObjectType), - name = interp_attrproperty('name', W_ObjectType), - attributes = GetSetProperty(W_ObjectType.get_attributes), - ) - -class W_ObjectAttribute(Wrappable): - def __init__(self, connection, param): - self.initialize(connection, param) - - def initialize(self, connection, param): - # determine the name of the attribute - nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, - flavor='raw') - lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, - flavor='raw') - try: - status = roci.OCIAttrGet( - param, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, nameptr), - lenptr, - roci.OCI_ATTR_NAME, - connection.environment.errorHandle) - connection.environment.checkForError( - status, - "ObjectAttribute_Initialize(): get name") - self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) - finally: - lltype.free(nameptr, flavor='raw') - lltype.free(lenptr, flavor='raw') - - # determine the type of the attribute - typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - param, roci.OCI_DTYPE_PARAM, - rffi.cast(roci.dvoidp, typecodeptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - roci.OCI_ATTR_TYPECODE, - connection.environment.errorHandle) - connection.environment.checkForError( - status, "ObjectType_Describe(): get type code") - self.typeCode = rffi.cast(lltype.Signed, typecodeptr[0]) - finally: - lltype.free(typecodeptr, flavor='raw') - - # if the type of the attribute is object, recurse - if self.typeCode in (roci.OCI_TYPECODE_NAMEDCOLLECTION, - roci.OCI_TYPECODE_OBJECT): - self.subType = W_ObjectType(connection, param) - else: - self.subType = None - -W_ObjectAttribute.typedef = TypeDef( - 'ObjectAttribute', - name = interp_attrproperty('name', W_ObjectAttribute), - ) - -class W_ExternalObject(Wrappable): - def __init__(self, var, objectType, instance, indicator, - isIndependent=True): - self.var = var # keepalive - self.objectType = objectType - self.instance = instance - self.indicator = indicator - self.isIndependent = isIndependent - - def getattr(self, space, attr): - try: - attribute = self.objectType.attributesByName[attr] - except KeyError: - msg = "ExternalObject has no attribute '%s'" %(attr,) - raise OperationError(space.w_AttributeError, space.wrap(msg)) - - environment = self.objectType.environment - - scalarvalueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.OCIInd).TO, - 1, flavor='raw') - valueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, - 1, flavor='raw') - valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, - 1, flavor='raw') - tdoptr = lltype.malloc(rffi.CArrayPtr(roci.OCIType).TO, - 1, flavor='raw') - nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, - 1, flavor='raw') - nameptr[0] = rffi.str2charp(attr) - namelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, - 1, flavor='raw') - namelenptr[0] = rffi.cast(roci.ub4, len(attr)) - - try: - status = roci.OCIObjectGetAttr( - environment.handle, - environment.errorHandle, - self.instance, - self.indicator, - self.objectType.tdo, - nameptr, namelenptr, 1, - lltype.nullptr(roci.Ptr(roci.ub4).TO), 0, - scalarvalueindicatorptr, - valueindicatorptr, - valueptr, - tdoptr) - environment.checkForError( - status, "ExternalObject_GetAttributeValue(): getting value") - - # determine the proper null indicator - valueIndicator = valueindicatorptr[0] - if not valueIndicator: - valueIndicator = rffi.cast(roci.dvoidp, - scalarvalueindicatorptr) - value = valueptr[0] - - return convertObject( - space, environment, - attribute.typeCode, - value, valueIndicator, - self, attribute.subType) - finally: - lltype.free(scalarvalueindicatorptr, flavor='raw') - lltype.free(valueindicatorptr, flavor='raw') - lltype.free(valueptr, flavor='raw') - lltype.free(tdoptr, flavor='raw') - rffi.free_charp(nameptr[0]) - lltype.free(nameptr, flavor='raw') - lltype.free(namelenptr, flavor='raw') - - getattr.unwrap_spec = ['self', ObjSpace, str] - -W_ExternalObject.typedef = TypeDef( - 'ExternalObject', - type = interp_attrproperty('objectType', W_ExternalObject), - __getattr__ = interp2app(W_ExternalObject.getattr), - ) - -def convertObject(space, environment, typeCode, - value, indicator, var, subtype): - - # null values returned as None - if (rffi.cast(lltype.Signed, - rffi.cast(roci.Ptr(roci.OCIInd), - indicator)[0]) - == - rffi.cast(lltype.Signed, roci.OCI_IND_NULL)): - return space.w_None - - if typeCode in (roci.OCI_TYPECODE_CHAR, - roci.OCI_TYPECODE_VARCHAR, - roci.OCI_TYPECODE_VARCHAR2): - strValue = rffi.cast(roci.Ptr(roci.OCIString), value)[0] - ptr = roci.OCIStringPtr(environment.handle, strValue) - size = roci.OCIStringSize(environment.handle, strValue) - return config.w_string(space, ptr, size) - elif typeCode == roci.OCI_TYPECODE_NUMBER: - return transform.OracleNumberToPythonFloat( - environment, - rffi.cast(roci.Ptr(roci.OCINumber), value)) - elif typeCode == roci.OCI_TYPECODE_DATE: - dateValue = rffi.cast(roci.Ptr(roci.OCIDate), value) - return transform.OracleDateToPythonDateTime(environment, dateValue) - elif typeCode == roci.OCI_TYPECODE_TIMESTAMP: - dateValue = rffi.cast(roci.Ptr(roci.OCIDateTime), value) - return transform.OracleTimestampToPythonDate(environment, dateValue) - elif typeCode == roci.OCI_TYPECODE_OBJECT: - return space.wrap(W_ExternalObject(var, subtype, value, indicator, - isIndependent=False)) - elif typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION: - return convertCollection(space, environment, value, var, subtype) - - raise OperationError( - get(space).w_NotSupportedError, - space.wrap( - "ExternalObjectVar_GetAttributeValue(): unhandled data type %d" % ( - typeCode,))) - - -def convertCollection(space, environment, value, var, objectType): - "Convert a collection to a Python list" - - result_w = [] - - iterptr = lltype.malloc(rffi.CArrayPtr(roci.OCIIter).TO, 1, flavor='raw') - try: - # create the iterator - status = roci.OCIIterCreate( - environment.handle, - environment.errorHandle, - value, - iterptr) - environment.checkForError( - status, "ExternalObjectVar_ConvertCollection(): creating iterator") - - try: - # create the result list - valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, - 1, flavor='raw') - indicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, - 1, flavor='raw') - eofptr = lltype.malloc(rffi.CArrayPtr(roci.boolean).TO, - 1, flavor='raw') - try: - while True: - status = roci.OCIIterNext( - environment.handle, - environment.errorHandle, - iterptr[0], - valueptr, - indicatorptr, - eofptr) - environment.checkForError( - status, - "ExternalObjectVar_ConvertCollection(): get next") - - if rffi.cast(lltype.Signed, eofptr[0]): - break - element = convertObject( - space, environment, - objectType.elementTypeCode, - valueptr[0], indicatorptr[0], - var, objectType.elementType) - result_w.append(element) - finally: - lltype.free(valueptr, flavor='raw') - lltype.free(indicatorptr, flavor='raw') - lltype.free(eofptr, flavor='raw') - - finally: - roci.OCIIterDelete( - environment.handle, - environment.errorHandle, - iterptr) - finally: - lltype.free(iterptr, flavor='raw') - - return space.newlist(result_w) - +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef, GetSetProperty +from pypy.interpreter.typedef import interp_attrproperty +from pypy.interpreter.gateway import ObjSpace +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.error import OperationError +from pypy.rpython.lltypesystem import rffi, lltype + +from pypy.module.oracle import roci, config, transform +from pypy.module.oracle.interp_error import get + +class W_ObjectType(Wrappable): + def __init__(self, connection, param): + self.tdo = lltype.nullptr(roci.dvoidp.TO) + self.environment = connection.environment + self.isCollection = False + self.initialize(connection, param) + + def __del__(self): + if self.tdo: + roci.OCIObjectUnpin( + self.environment.handle, + self.environment.errorHandle, + self.tdo) + + def initialize(self, connection, param): + nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, + flavor='raw') + lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, + flavor='raw') + try: + # determine the schema of the type + status = roci.OCIAttrGet( + param, roci.OCI_HTYPE_DESCRIBE, + rffi.cast(roci.dvoidp, nameptr), + lenptr, + roci.OCI_ATTR_SCHEMA_NAME, + self.environment.errorHandle) + self.environment.checkForError( + status, + "ObjectType_Initialize(): get schema name") + self.schema = rffi.charpsize2str(nameptr[0], lenptr[0]) + + # determine the name of the type + status = roci.OCIAttrGet( + param, roci.OCI_HTYPE_DESCRIBE, + rffi.cast(roci.dvoidp, nameptr), + lenptr, + roci.OCI_ATTR_TYPE_NAME, + self.environment.errorHandle) + self.environment.checkForError( + status, + "ObjectType_Initialize(): get schema name") + self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) + finally: + lltype.free(nameptr, flavor='raw') + lltype.free(lenptr, flavor='raw') + + # retrieve TDO (type descriptor object) of the parameter + tdorefptr = lltype.malloc(rffi.CArrayPtr(roci.OCIRef).TO, 1, + flavor='raw') + try: + status = roci.OCIAttrGet( + param, roci.OCI_HTYPE_DESCRIBE, + rffi.cast(roci.dvoidp, tdorefptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_REF_TDO, + self.environment.errorHandle) + self.environment.checkForError( + status, + "ObjectType_Initialize(): get TDO reference") + tdoref = tdorefptr[0] + finally: + lltype.free(tdorefptr, flavor='raw') + + tdoptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, + flavor='raw') + try: + status = roci.OCIObjectPin( + self.environment.handle, + self.environment.errorHandle, + tdoref, + None, roci.OCI_PIN_ANY, + roci.OCI_DURATION_SESSION, roci.OCI_LOCK_NONE, + tdoptr) + self.environment.checkForError( + status, + "ObjectType_Initialize(): pin TDO reference") + self.tdo = tdoptr[0] + finally: + lltype.free(tdoptr, flavor='raw') + + # acquire a describe handle + handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIDescribe).TO, + 1, flavor='raw') + try: + status = roci.OCIHandleAlloc( + self.environment.handle, + handleptr, roci.OCI_HTYPE_DESCRIBE, 0, + lltype.nullptr(rffi.CArray(roci.dvoidp))) + self.environment.checkForError( + status, "ObjectType_Initialize(): allocate describe handle") + describeHandle = handleptr[0] + finally: + lltype.free(handleptr, flavor='raw') + + # describe the type + try: + self.describe(connection, describeHandle) + finally: + roci.OCIHandleFree(describeHandle, roci.OCI_HTYPE_DESCRIBE) + + def describe(self, connection, describeHandle): + "Describe the type and store information about it as needed" + + # describe the type + status = roci.OCIDescribeAny( + connection.handle, + self.environment.errorHandle, + self.tdo, 0, + roci.OCI_OTYPE_PTR, + roci.OCI_DEFAULT, + roci.OCI_PTYPE_TYPE, + describeHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): describe type") + + # get top level parameter descriptor + paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + describeHandle, roci.OCI_HTYPE_DESCRIBE, + rffi.cast(roci.dvoidp, paramptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_PARAM, + self.environment.errorHandle) + self.environment.checkForError( + status, + "ObjectType_Describe(): get top level parameter descriptor") + toplevelParam = paramptr[0] + finally: + lltype.free(paramptr, flavor='raw') + + # determine type of type + typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + toplevelParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, typecodeptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_TYPECODE, + self.environment.errorHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): get type code") + typeCode = rffi.cast(lltype.Signed, typecodeptr[0]) + finally: + lltype.free(typecodeptr, flavor='raw') + + # if a collection, need to determine the sub type + if typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION: + self.isCollection = 1 + + # determine type of collection + typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + toplevelParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, typecodeptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_TYPECODE, + self.environment.errorHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): get collection type code") + self.collectionTypeCode = typecodeptr[0] + finally: + lltype.free(typecodeptr, flavor='raw') + + # acquire collection parameter descriptor + paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + toplevelParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, paramptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_COLLECTION_ELEMENT, + self.environment.errorHandle) + self.environment.checkForError( + status, + "ObjectType_Describe(): get collection descriptor") + collectionParam = paramptr[0] + finally: + lltype.free(paramptr, flavor='raw') + + # determine type of element + typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + collectionParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, typecodeptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_TYPECODE, + self.environment.errorHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): get element type code") + self.elementTypeCode = rffi.cast(lltype.Signed, typecodeptr[0]) + finally: + lltype.free(typecodeptr, flavor='raw') + + # if element type is an object type get its type + if self.elementTypeCode == roci.OCI_TYPECODE_OBJECT: + self.elementType = W_ObjectType(connection, collectionParam) + else: + self.elementType = None + + # determine the number of attributes + numptr = lltype.malloc(roci.Ptr(roci.ub2).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + toplevelParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, numptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_NUM_TYPE_ATTRS, + self.environment.errorHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): get number of attributes") + numAttributes = numptr[0] + finally: + lltype.free(numptr, flavor='raw') + + # allocate the attribute list and dictionary + self.attributes = [] + self.attributesByName = {} + + # acquire the list parameter descriptor + listptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + toplevelParam, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, listptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_LIST_TYPE_ATTRS, + self.environment.errorHandle) + self.environment.checkForError( + status, "ObjectType_Describe(): get list parameter descriptor") + attributeListParam = listptr[0] + finally: + lltype.free(listptr, flavor='raw') + + # create attribute information for each attribute + for i in range(numAttributes): + paramptr = lltype.malloc(roci.Ptr(roci.OCIParam).TO, + 1, flavor='raw') + try: + status = roci.OCIParamGet( + attributeListParam, roci.OCI_DTYPE_PARAM, + self.environment.errorHandle, + paramptr, i + 1) + self.environment.checkForError( + status, + "ObjectType_Describe(): get attribute param descriptor") + attribute = W_ObjectAttribute(connection, paramptr[0]) + finally: + lltype.free(paramptr, flavor='raw') + + self.attributes.append(attribute) + self.attributesByName[attribute.name] = attribute + + def get_attributes(space, self): + return space.newlist([space.wrap(attr) for attr in self.attributes]) + +W_ObjectType.typedef = TypeDef( + 'ObjectType', + schema = interp_attrproperty('schema', W_ObjectType), + name = interp_attrproperty('name', W_ObjectType), + attributes = GetSetProperty(W_ObjectType.get_attributes), + ) + +class W_ObjectAttribute(Wrappable): + def __init__(self, connection, param): + self.initialize(connection, param) + + def initialize(self, connection, param): + # determine the name of the attribute + nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, + flavor='raw') + lenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, + flavor='raw') + try: + status = roci.OCIAttrGet( + param, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, nameptr), + lenptr, + roci.OCI_ATTR_NAME, + connection.environment.errorHandle) + connection.environment.checkForError( + status, + "ObjectAttribute_Initialize(): get name") + self.name = rffi.charpsize2str(nameptr[0], lenptr[0]) + finally: + lltype.free(nameptr, flavor='raw') + lltype.free(lenptr, flavor='raw') + + # determine the type of the attribute + typecodeptr = lltype.malloc(roci.Ptr(roci.OCITypeCode).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + param, roci.OCI_DTYPE_PARAM, + rffi.cast(roci.dvoidp, typecodeptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + roci.OCI_ATTR_TYPECODE, + connection.environment.errorHandle) + connection.environment.checkForError( + status, "ObjectType_Describe(): get type code") + self.typeCode = rffi.cast(lltype.Signed, typecodeptr[0]) + finally: + lltype.free(typecodeptr, flavor='raw') + + # if the type of the attribute is object, recurse + if self.typeCode in (roci.OCI_TYPECODE_NAMEDCOLLECTION, + roci.OCI_TYPECODE_OBJECT): + self.subType = W_ObjectType(connection, param) + else: + self.subType = None + +W_ObjectAttribute.typedef = TypeDef( + 'ObjectAttribute', + name = interp_attrproperty('name', W_ObjectAttribute), + ) + +class W_ExternalObject(Wrappable): + def __init__(self, var, objectType, instance, indicator, + isIndependent=True): + self.var = var # keepalive + self.objectType = objectType + self.instance = instance + self.indicator = indicator + self.isIndependent = isIndependent + + def getattr(self, space, attr): + try: + attribute = self.objectType.attributesByName[attr] + except KeyError: + msg = "ExternalObject has no attribute '%s'" %(attr,) + raise OperationError(space.w_AttributeError, space.wrap(msg)) + + environment = self.objectType.environment + + scalarvalueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.OCIInd).TO, + 1, flavor='raw') + valueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, + 1, flavor='raw') + valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, + 1, flavor='raw') + tdoptr = lltype.malloc(rffi.CArrayPtr(roci.OCIType).TO, + 1, flavor='raw') + nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, + 1, flavor='raw') + nameptr[0] = rffi.str2charp(attr) + namelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, + 1, flavor='raw') + namelenptr[0] = rffi.cast(roci.ub4, len(attr)) + + try: + status = roci.OCIObjectGetAttr( + environment.handle, + environment.errorHandle, + self.instance, + self.indicator, + self.objectType.tdo, + nameptr, namelenptr, 1, + lltype.nullptr(roci.Ptr(roci.ub4).TO), 0, + scalarvalueindicatorptr, + valueindicatorptr, + valueptr, + tdoptr) + environment.checkForError( + status, "ExternalObject_GetAttributeValue(): getting value") + + # determine the proper null indicator + valueIndicator = valueindicatorptr[0] + if not valueIndicator: + valueIndicator = rffi.cast(roci.dvoidp, + scalarvalueindicatorptr) + value = valueptr[0] + + return convertObject( + space, environment, + attribute.typeCode, + value, valueIndicator, + self, attribute.subType) + finally: + lltype.free(scalarvalueindicatorptr, flavor='raw') + lltype.free(valueindicatorptr, flavor='raw') + lltype.free(valueptr, flavor='raw') + lltype.free(tdoptr, flavor='raw') + rffi.free_charp(nameptr[0]) + lltype.free(nameptr, flavor='raw') + lltype.free(namelenptr, flavor='raw') + + getattr.unwrap_spec = ['self', ObjSpace, str] + +W_ExternalObject.typedef = TypeDef( + 'ExternalObject', + type = interp_attrproperty('objectType', W_ExternalObject), + __getattr__ = interp2app(W_ExternalObject.getattr), + ) + +def convertObject(space, environment, typeCode, + value, indicator, var, subtype): + + # null values returned as None + if (rffi.cast(lltype.Signed, + rffi.cast(roci.Ptr(roci.OCIInd), + indicator)[0]) + == + rffi.cast(lltype.Signed, roci.OCI_IND_NULL)): + return space.w_None + + if typeCode in (roci.OCI_TYPECODE_CHAR, + roci.OCI_TYPECODE_VARCHAR, + roci.OCI_TYPECODE_VARCHAR2): + strValue = rffi.cast(roci.Ptr(roci.OCIString), value)[0] + ptr = roci.OCIStringPtr(environment.handle, strValue) + size = roci.OCIStringSize(environment.handle, strValue) + return config.w_string(space, ptr, size) + elif typeCode == roci.OCI_TYPECODE_NUMBER: + return transform.OracleNumberToPythonFloat( + environment, + rffi.cast(roci.Ptr(roci.OCINumber), value)) + elif typeCode == roci.OCI_TYPECODE_DATE: + dateValue = rffi.cast(roci.Ptr(roci.OCIDate), value) + return transform.OracleDateToPythonDateTime(environment, dateValue) + elif typeCode == roci.OCI_TYPECODE_TIMESTAMP: + dateValue = rffi.cast(roci.Ptr(roci.OCIDateTime), value) + return transform.OracleTimestampToPythonDate(environment, dateValue) + elif typeCode == roci.OCI_TYPECODE_OBJECT: + return space.wrap(W_ExternalObject(var, subtype, value, indicator, + isIndependent=False)) + elif typeCode == roci.OCI_TYPECODE_NAMEDCOLLECTION: + return convertCollection(space, environment, value, var, subtype) + + raise OperationError( + get(space).w_NotSupportedError, + space.wrap( + "ExternalObjectVar_GetAttributeValue(): unhandled data type %d" % ( + typeCode,))) + + +def convertCollection(space, environment, value, var, objectType): + "Convert a collection to a Python list" + + result_w = [] + + iterptr = lltype.malloc(rffi.CArrayPtr(roci.OCIIter).TO, 1, flavor='raw') + try: + # create the iterator + status = roci.OCIIterCreate( + environment.handle, + environment.errorHandle, + value, + iterptr) + environment.checkForError( + status, "ExternalObjectVar_ConvertCollection(): creating iterator") + + try: + # create the result list + valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, + 1, flavor='raw') + indicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, + 1, flavor='raw') + eofptr = lltype.malloc(rffi.CArrayPtr(roci.boolean).TO, + 1, flavor='raw') + try: + while True: + status = roci.OCIIterNext( + environment.handle, + environment.errorHandle, + iterptr[0], + valueptr, + indicatorptr, + eofptr) + environment.checkForError( + status, + "ExternalObjectVar_ConvertCollection(): get next") + + if rffi.cast(lltype.Signed, eofptr[0]): + break + element = convertObject( + space, environment, + objectType.elementTypeCode, + valueptr[0], indicatorptr[0], + var, objectType.elementType) + result_w.append(element) + finally: + lltype.free(valueptr, flavor='raw') + lltype.free(indicatorptr, flavor='raw') + lltype.free(eofptr, flavor='raw') + + finally: + roci.OCIIterDelete( + environment.handle, + environment.errorHandle, + iterptr) + finally: + lltype.free(iterptr, flavor='raw') + + return space.newlist(result_w) + Modified: pypy/trunk/pypy/module/oracle/interp_pool.py ============================================================================== --- pypy/trunk/pypy/module/oracle/interp_pool.py (original) +++ pypy/trunk/pypy/module/oracle/interp_pool.py Tue Mar 9 15:46:14 2010 @@ -1,216 +1,216 @@ -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.argument import Arguments, Signature -from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped -from pypy.interpreter.gateway import interp2app -from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w -from pypy.interpreter.error import OperationError -from pypy.rpython.lltypesystem import rffi, lltype - -Null = NoneNotWrapped - -from pypy.module.oracle import roci, config -from pypy.module.oracle import interp_error, interp_environ -from pypy.module.oracle.interp_error import get - -class W_SessionPool(Wrappable): - def __init__(self): - self.environment = None - - def descr_new(space, w_subtype, - w_user, w_password, w_dsn, - min, max, increment, - w_connectiontype=Null, - threaded=False, - getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT, - events=False, - homogeneous=True): - self = space.allocate_instance(W_SessionPool, w_subtype) - W_SessionPool.__init__(self) - - if w_connectiontype is not None: - if not space.is_true(space.issubtype(w_connectiontype, - get(space).w_Connection)): - raise OperationError( - interp_error.get(space).w_ProgrammingError, - space.wrap( - "connectiontype must be a subclass of Connection")) - self.w_connectionType = w_connectiontype - else: - self.w_connectionType = get(space).w_Connection - - self.w_username = w_user - self.w_password = w_password - self.w_tnsentry = w_dsn - - self.minSessions = min - self.maxSessions = max - self.sessionIncrement = increment - self.homogeneous = homogeneous - - # set up the environment - self.environment = interp_environ.Environment.create( - space, threaded, events) - - # create the session pool handle - handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO, - 1, flavor='raw') - try: - status = roci.OCIHandleAlloc( - self.environment.handle, - handleptr, roci.OCI_HTYPE_SPOOL, 0, - lltype.nullptr(rffi.CArray(roci.dvoidp))) - self.environment.checkForError( - status, "SessionPool_New(): allocate handle") - self.handle = handleptr[0] - finally: - lltype.free(handleptr, flavor='raw') - - # prepare pool mode - poolMode = roci.OCI_SPC_STMTCACHE - if self.homogeneous: - poolMode |= roci.OCI_SPC_HOMOGENEOUS - - # create the session pool - user_buf = config.StringBuffer() - user_buf.fill(space, self.w_username) - password_buf = config.StringBuffer() - password_buf.fill(space, self.w_password) - dsn_buf = config.StringBuffer() - dsn_buf.fill(space, self.w_tnsentry) - poolnameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, - flavor='raw') - poolnamelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, - flavor='raw') - - try: - status = roci.OCISessionPoolCreate( - self.environment.handle, - self.environment.errorHandle, - self.handle, - poolnameptr, poolnamelenptr, - dsn_buf.ptr, dsn_buf.size, - min, max, increment, - user_buf.ptr, user_buf.size, - password_buf.ptr, password_buf.size, - poolMode) - self.environment.checkForError( - status, "SessionPool_New(): create pool") - - self.w_name = config.w_string(space, poolnameptr[0], - poolnamelenptr[0]) - finally: - user_buf.clear() - password_buf.clear() - dsn_buf.clear() - - return space.wrap(self) - descr_new.unwrap_spec = [ObjSpace, W_Root, - W_Root, W_Root, W_Root, - int, int, int, - W_Root, - bool, int, bool, bool] - - def checkConnected(self, space): - if not self.handle: - raise OperationError( - get(space).w_InterfaceError, - space.wrap("not connected")) - - def acquire(self, space, __args__): - (w_user, w_password, w_cclass, w_purity - ) = __args__.parse_obj( - None, "acquire", - Signature(["user", "password", "cclass", "purity"]), - defaults_w=[None, None, None, space.w_False]) - if self.homogeneous and (w_user or w_password): - raise OperationError( - get(space).w_ProgrammingError, - space.wrap("pool is homogeneous. " - "Proxy authentication is not possible.")) - - self.checkConnected(space) - - newargs = Arguments(space, - __args__.arguments_w, - __args__.keywords + ["pool"], - __args__.keywords_w + [space.wrap(self)]) - return space.call_args(self.w_connectionType, newargs) - acquire.unwrap_spec = ['self', ObjSpace, Arguments] - - def release(self, space, w_connection): - self._release(space, w_connection, roci.OCI_DEFAULT) - release.unwrap_spec = ['self', ObjSpace, W_Root] - - def drop(self, space, w_connection): - self._release(space, w_connection, roci.OCI_SESSRLS_DROPSESS) - drop.unwrap_spec = ['self', ObjSpace, W_Root] - - def _release(self, space, w_connection, mode): - from pypy.module.oracle.interp_connect import W_Connection - connection = space.interp_w(W_Connection, w_connection) - - self.checkConnected(space) - - if connection.sessionPool is not self: - raise OperationError( - get(space).w_ProgrammingError, - space.wrap("connection not acquired with this session pool")) - - # attempt a rollback - status = roci.OCITransRollback( - connection.handle, connection.environment.errorHandle, - roci.OCI_DEFAULT) - # if dropping the connection from the pool, ignore the error - if mode != roci.OCI_SESSRLS_DROPSESS: - self.environment.checkForError( - status, "SessionPool_Release(): rollback") - - # release the connection - status = roci.OCISessionRelease( - connection.handle, connection.environment.errorHandle, - None, 0, mode) - self.environment.checkForError( - status, "SessionPool_Release(): release session") - - # ensure that the connection behaves as closed - connection.sessionPool = None - connection.handle = lltype.nullptr(roci.OCISvcCtx.TO) - -def computedProperty(oci_attr_code, oci_value_type): - def fget(space, self): - self.checkConnected(space) - - valueptr = lltype.malloc(rffi.CArrayPtr(oci_value_type).TO, - 1, flavor='raw') - try: - status = roci.OCIAttrGet( - self.handle, roci.OCI_HTYPE_SPOOL, - rffi.cast(roci.dvoidp, valueptr), - lltype.nullptr(roci.Ptr(roci.ub4).TO), - oci_attr_code, - self.environment.errorHandle) - return space.wrap(valueptr[0]) - finally: - lltype.free(valueptr, flavor='raw') - return GetSetProperty(fget, cls=W_SessionPool) - -W_SessionPool.typedef = TypeDef( - "SessionPool", - __new__ = interp2app(W_SessionPool.descr_new.im_func), - acquire = interp2app(W_SessionPool.acquire), - release = interp2app(W_SessionPool.release), - drop = interp2app(W_SessionPool.drop), - - username = interp_attrproperty_w('w_username', W_SessionPool), - password = interp_attrproperty_w('w_password', W_SessionPool), - tnsentry = interp_attrproperty_w('w_tnsentry', W_SessionPool), - min = interp_attrproperty('minSessions', W_SessionPool), - max = interp_attrproperty('maxSessions', W_SessionPool), - increment = interp_attrproperty('sessionIncrement', W_SessionPool), - homogeneous = interp_attrproperty('homogeneous', W_SessionPool), - opened = computedProperty(roci.OCI_ATTR_SPOOL_OPEN_COUNT, roci.ub4), - busy = computedProperty(roci.OCI_ATTR_SPOOL_BUSY_COUNT, roci.ub4), - timeout = computedProperty(roci.OCI_ATTR_SPOOL_TIMEOUT, roci.ub4), - getmode = computedProperty(roci.OCI_ATTR_SPOOL_GETMODE, roci.ub1), - ) +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.argument import Arguments, Signature +from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.typedef import TypeDef, GetSetProperty +from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w +from pypy.interpreter.error import OperationError +from pypy.rpython.lltypesystem import rffi, lltype + +Null = NoneNotWrapped + +from pypy.module.oracle import roci, config +from pypy.module.oracle import interp_error, interp_environ +from pypy.module.oracle.interp_error import get + +class W_SessionPool(Wrappable): + def __init__(self): + self.environment = None + + def descr_new(space, w_subtype, + w_user, w_password, w_dsn, + min, max, increment, + w_connectiontype=Null, + threaded=False, + getmode=roci.OCI_SPOOL_ATTRVAL_NOWAIT, + events=False, + homogeneous=True): + self = space.allocate_instance(W_SessionPool, w_subtype) + W_SessionPool.__init__(self) + + if w_connectiontype is not None: + if not space.is_true(space.issubtype(w_connectiontype, + get(space).w_Connection)): + raise OperationError( + interp_error.get(space).w_ProgrammingError, + space.wrap( + "connectiontype must be a subclass of Connection")) + self.w_connectionType = w_connectiontype + else: + self.w_connectionType = get(space).w_Connection + + self.w_username = w_user + self.w_password = w_password + self.w_tnsentry = w_dsn + + self.minSessions = min + self.maxSessions = max + self.sessionIncrement = increment + self.homogeneous = homogeneous + + # set up the environment + self.environment = interp_environ.Environment.create( + space, threaded, events) + + # create the session pool handle + handleptr = lltype.malloc(rffi.CArrayPtr(roci.OCIServer).TO, + 1, flavor='raw') + try: + status = roci.OCIHandleAlloc( + self.environment.handle, + handleptr, roci.OCI_HTYPE_SPOOL, 0, + lltype.nullptr(rffi.CArray(roci.dvoidp))) + self.environment.checkForError( + status, "SessionPool_New(): allocate handle") + self.handle = handleptr[0] + finally: + lltype.free(handleptr, flavor='raw') + + # prepare pool mode + poolMode = roci.OCI_SPC_STMTCACHE + if self.homogeneous: + poolMode |= roci.OCI_SPC_HOMOGENEOUS + + # create the session pool + user_buf = config.StringBuffer() + user_buf.fill(space, self.w_username) + password_buf = config.StringBuffer() + password_buf.fill(space, self.w_password) + dsn_buf = config.StringBuffer() + dsn_buf.fill(space, self.w_tnsentry) + poolnameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, + flavor='raw') + poolnamelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, + flavor='raw') + + try: + status = roci.OCISessionPoolCreate( + self.environment.handle, + self.environment.errorHandle, + self.handle, + poolnameptr, poolnamelenptr, + dsn_buf.ptr, dsn_buf.size, + min, max, increment, + user_buf.ptr, user_buf.size, + password_buf.ptr, password_buf.size, + poolMode) + self.environment.checkForError( + status, "SessionPool_New(): create pool") + + self.w_name = config.w_string(space, poolnameptr[0], + poolnamelenptr[0]) + finally: + user_buf.clear() + password_buf.clear() + dsn_buf.clear() + + return space.wrap(self) + descr_new.unwrap_spec = [ObjSpace, W_Root, + W_Root, W_Root, W_Root, + int, int, int, + W_Root, + bool, int, bool, bool] + + def checkConnected(self, space): + if not self.handle: + raise OperationError( + get(space).w_InterfaceError, + space.wrap("not connected")) + + def acquire(self, space, __args__): + (w_user, w_password, w_cclass, w_purity + ) = __args__.parse_obj( + None, "acquire", + Signature(["user", "password", "cclass", "purity"]), + defaults_w=[None, None, None, space.w_False]) + if self.homogeneous and (w_user or w_password): + raise OperationError( + get(space).w_ProgrammingError, + space.wrap("pool is homogeneous. " + "Proxy authentication is not possible.")) + + self.checkConnected(space) + + newargs = Arguments(space, + __args__.arguments_w, + __args__.keywords + ["pool"], + __args__.keywords_w + [space.wrap(self)]) + return space.call_args(self.w_connectionType, newargs) + acquire.unwrap_spec = ['self', ObjSpace, Arguments] + + def release(self, space, w_connection): + self._release(space, w_connection, roci.OCI_DEFAULT) + release.unwrap_spec = ['self', ObjSpace, W_Root] + + def drop(self, space, w_connection): + self._release(space, w_connection, roci.OCI_SESSRLS_DROPSESS) + drop.unwrap_spec = ['self', ObjSpace, W_Root] + + def _release(self, space, w_connection, mode): + from pypy.module.oracle.interp_connect import W_Connection + connection = space.interp_w(W_Connection, w_connection) + + self.checkConnected(space) + + if connection.sessionPool is not self: + raise OperationError( + get(space).w_ProgrammingError, + space.wrap("connection not acquired with this session pool")) + + # attempt a rollback + status = roci.OCITransRollback( + connection.handle, connection.environment.errorHandle, + roci.OCI_DEFAULT) + # if dropping the connection from the pool, ignore the error + if mode != roci.OCI_SESSRLS_DROPSESS: + self.environment.checkForError( + status, "SessionPool_Release(): rollback") + + # release the connection + status = roci.OCISessionRelease( + connection.handle, connection.environment.errorHandle, + None, 0, mode) + self.environment.checkForError( + status, "SessionPool_Release(): release session") + + # ensure that the connection behaves as closed + connection.sessionPool = None + connection.handle = lltype.nullptr(roci.OCISvcCtx.TO) + +def computedProperty(oci_attr_code, oci_value_type): + def fget(space, self): + self.checkConnected(space) + + valueptr = lltype.malloc(rffi.CArrayPtr(oci_value_type).TO, + 1, flavor='raw') + try: + status = roci.OCIAttrGet( + self.handle, roci.OCI_HTYPE_SPOOL, + rffi.cast(roci.dvoidp, valueptr), + lltype.nullptr(roci.Ptr(roci.ub4).TO), + oci_attr_code, + self.environment.errorHandle) + return space.wrap(valueptr[0]) + finally: + lltype.free(valueptr, flavor='raw') + return GetSetProperty(fget, cls=W_SessionPool) + +W_SessionPool.typedef = TypeDef( + "SessionPool", + __new__ = interp2app(W_SessionPool.descr_new.im_func), + acquire = interp2app(W_SessionPool.acquire), + release = interp2app(W_SessionPool.release), + drop = interp2app(W_SessionPool.drop), + + username = interp_attrproperty_w('w_username', W_SessionPool), + password = interp_attrproperty_w('w_password', W_SessionPool), + tnsentry = interp_attrproperty_w('w_tnsentry', W_SessionPool), + min = interp_attrproperty('minSessions', W_SessionPool), + max = interp_attrproperty('maxSessions', W_SessionPool), + increment = interp_attrproperty('sessionIncrement', W_SessionPool), + homogeneous = interp_attrproperty('homogeneous', W_SessionPool), + opened = computedProperty(roci.OCI_ATTR_SPOOL_OPEN_COUNT, roci.ub4), + busy = computedProperty(roci.OCI_ATTR_SPOOL_BUSY_COUNT, roci.ub4), + timeout = computedProperty(roci.OCI_ATTR_SPOOL_TIMEOUT, roci.ub4), + getmode = computedProperty(roci.OCI_ATTR_SPOOL_GETMODE, roci.ub1), + ) Modified: pypy/trunk/pypy/module/oracle/test/test_cursorvar.py ============================================================================== --- pypy/trunk/pypy/module/oracle/test/test_cursorvar.py (original) +++ pypy/trunk/pypy/module/oracle/test/test_cursorvar.py Tue Mar 9 15:46:14 2010 @@ -1,45 +1,45 @@ -from pypy.module.oracle.test.test_connect import OracleTestBase - -class AppTestCursorVar(OracleTestBase): - - def test_bind_inout(self): - cur = self.cnx.cursor() - cursor = self.cnx.cursor() - assert cursor.description is None - cur.execute(""" - begin - open :cursor for select 1 numbercol from dual; - end;""", - cursor=cursor) - assert (cursor.description == - [('NUMBERCOL', oracle.NUMBER, 127, 2, 0, 0, 1)] - or cursor.description == - [('NUMBERCOL', oracle.NUMBER, 127, 2, 0, -127, 1)]) - data = cursor.fetchall() - assert data == [(1,)] - - def test_bind_frompackage(self): - cur = self.cnx.cursor() - # create package - try: - cur.execute("drop package pypy_temp_cursorpkg") - except oracle.DatabaseError: - pass - cur.execute(""" - create package pypy_temp_cursorpkg as - type refcur is ref cursor; - procedure test_cursor(cur out refcur); - end;""") - cur.execute(""" - create package body pypy_temp_cursorpkg as - procedure test_cursor(cur out refcur) is - begin - open cur for - select level-1 intcol - from dual connect by level-1<42; - end; - end;""") - cursor = self.cnx.cursor() - cur.callproc("pypy_temp_cursorpkg.test_cursor", (cursor,)) - data = cursor.fetchall() - assert data == [(x,) for x in range(42)] +from pypy.module.oracle.test.test_connect import OracleTestBase + +class AppTestCursorVar(OracleTestBase): + + def test_bind_inout(self): + cur = self.cnx.cursor() + cursor = self.cnx.cursor() + assert cursor.description is None + cur.execute(""" + begin + open :cursor for select 1 numbercol from dual; + end;""", + cursor=cursor) + assert (cursor.description == + [('NUMBERCOL', oracle.NUMBER, 127, 2, 0, 0, 1)] + or cursor.description == + [('NUMBERCOL', oracle.NUMBER, 127, 2, 0, -127, 1)]) + data = cursor.fetchall() + assert data == [(1,)] + + def test_bind_frompackage(self): + cur = self.cnx.cursor() + # create package + try: + cur.execute("drop package pypy_temp_cursorpkg") + except oracle.DatabaseError: + pass + cur.execute(""" + create package pypy_temp_cursorpkg as + type refcur is ref cursor; + procedure test_cursor(cur out refcur); + end;""") + cur.execute(""" + create package body pypy_temp_cursorpkg as + procedure test_cursor(cur out refcur) is + begin + open cur for + select level-1 intcol + from dual connect by level-1<42; + end; + end;""") + cursor = self.cnx.cursor() + cur.callproc("pypy_temp_cursorpkg.test_cursor", (cursor,)) + data = cursor.fetchall() + assert data == [(x,) for x in range(42)] Modified: pypy/trunk/pypy/module/oracle/test/test_lobvar.py ============================================================================== --- pypy/trunk/pypy/module/oracle/test/test_lobvar.py (original) +++ pypy/trunk/pypy/module/oracle/test/test_lobvar.py Tue Mar 9 15:46:14 2010 @@ -1,61 +1,61 @@ -from pypy.module.oracle.test.test_connect import OracleTestBase - -class LobTests(object): - @classmethod - def setup_class(cls): - super(LobTests, cls).setup_class() - cls.w_lobType = cls.space.wrap(cls.lobType) - - def test_bind(self): - inputType = getattr(oracle, self.lobType) - - cur = self.cnx.cursor() - try: - cur.execute("drop table pypy_temp_lobtable") - except oracle.DatabaseError: - pass - cur.execute("create table pypy_temp_lobtable " - "(lobcol %s)" % self.lobType) - - longString = "" - for i in range(2): - cur.execute("truncate table pypy_temp_lobtable") - if i > 0: - longString += chr(65+i) * 25000 - - cur.setinputsizes(lob=inputType) - cur.execute("insert into pypy_temp_lobtable values (:lob)", - lob=longString) - cur.execute("select lobcol from pypy_temp_lobtable") - lob, = cur.fetchone() - assert lob.size() == len(longString) - assert lob.read() == longString - - def test_trim(self): - inputType = getattr(oracle, self.lobType) - - cur = self.cnx.cursor() - try: - cur.execute("drop table pypy_temp_lobtable") - except oracle.DatabaseError: - pass - cur.execute("create table pypy_temp_lobtable " - "(lobcol %s)" % self.lobType) - - longString = "X" * 75000 - cur.setinputsizes(lob=inputType) - cur.execute("insert into pypy_temp_lobtable values (:lob)", - lob=longString) - cur.execute("select lobcol from pypy_temp_lobtable") - lob, = cur.fetchone() - assert lob.size() == 75000 - lob.trim(25000) - assert lob.size() == 25000 - lob.trim() - assert lob.size() == 0 - -class AppTestBlob(LobTests, OracleTestBase): - lobType = "BLOB" - -class AppTestClob(LobTests, OracleTestBase): - lobType = "CLOB" +from pypy.module.oracle.test.test_connect import OracleTestBase + +class LobTests(object): + @classmethod + def setup_class(cls): + super(LobTests, cls).setup_class() + cls.w_lobType = cls.space.wrap(cls.lobType) + + def test_bind(self): + inputType = getattr(oracle, self.lobType) + + cur = self.cnx.cursor() + try: + cur.execute("drop table pypy_temp_lobtable") + except oracle.DatabaseError: + pass + cur.execute("create table pypy_temp_lobtable " + "(lobcol %s)" % self.lobType) + + longString = "" + for i in range(2): + cur.execute("truncate table pypy_temp_lobtable") + if i > 0: + longString += chr(65+i) * 25000 + + cur.setinputsizes(lob=inputType) + cur.execute("insert into pypy_temp_lobtable values (:lob)", + lob=longString) + cur.execute("select lobcol from pypy_temp_lobtable") + lob, = cur.fetchone() + assert lob.size() == len(longString) + assert lob.read() == longString + + def test_trim(self): + inputType = getattr(oracle, self.lobType) + + cur = self.cnx.cursor() + try: + cur.execute("drop table pypy_temp_lobtable") + except oracle.DatabaseError: + pass + cur.execute("create table pypy_temp_lobtable " + "(lobcol %s)" % self.lobType) + + longString = "X" * 75000 + cur.setinputsizes(lob=inputType) + cur.execute("insert into pypy_temp_lobtable values (:lob)", + lob=longString) + cur.execute("select lobcol from pypy_temp_lobtable") + lob, = cur.fetchone() + assert lob.size() == 75000 + lob.trim(25000) + assert lob.size() == 25000 + lob.trim() + assert lob.size() == 0 + +class AppTestBlob(LobTests, OracleTestBase): + lobType = "BLOB" + +class AppTestClob(LobTests, OracleTestBase): + lobType = "CLOB" Modified: pypy/trunk/pypy/module/oracle/test/test_objectvar.py ============================================================================== --- pypy/trunk/pypy/module/oracle/test/test_objectvar.py (original) +++ pypy/trunk/pypy/module/oracle/test/test_objectvar.py Tue Mar 9 15:46:14 2010 @@ -1,50 +1,50 @@ -from pypy.module.oracle.test.test_connect import OracleTestBase - -class AppTestObjectVar(OracleTestBase): - def test_fetch_object(self): - import datetime - cur = self.cnx.cursor() - try: - cur.execute("drop table pypy_test_objtable") - except oracle.DatabaseError: - pass - try: - cur.execute("drop type pypy_test_objtype") - except oracle.DatabaseError: - pass - try: - cur.execute("drop type pypy_test_arraytype") - except oracle.DatabaseError: - pass - cur.execute("""\ - create type pypy_test_objtype as object ( - numbercol number, - stringcol varchar2(60), - datecol date); - """) - cur.execute("""\ - create type pypy_test_arraytype as varray(10) of number; - """) - cur.execute("""\ - create table pypy_test_objtable ( - objcol pypy_test_objtype, - arraycol pypy_test_arraytype) - """) - cur.execute("""\ - insert into pypy_test_objtable values ( - pypy_test_objtype(1, 'someText', - to_date(20070306, 'YYYYMMDD')), - pypy_test_arraytype(5, 10, null, 20)) - """) - - cur.execute("select objcol, arraycol from pypy_test_objtable") - objValue, arrayValue = cur.fetchone() - assert objValue.type.schema == self.cnx.username.upper() - assert objValue.type.name == "PYPY_TEST_OBJTYPE" - assert objValue.type.attributes[0].name == "NUMBERCOL" - assert isinstance(arrayValue, list) - assert arrayValue == [5, 10, None, 20] - assert objValue.NUMBERCOL == 1 - assert objValue.STRINGCOL == "someText" - assert objValue.DATECOL == datetime.datetime(2007, 03, 06) - raises(AttributeError, getattr, objValue, 'OTHER') +from pypy.module.oracle.test.test_connect import OracleTestBase + +class AppTestObjectVar(OracleTestBase): + def test_fetch_object(self): + import datetime + cur = self.cnx.cursor() + try: + cur.execute("drop table pypy_test_objtable") + except oracle.DatabaseError: + pass + try: + cur.execute("drop type pypy_test_objtype") + except oracle.DatabaseError: + pass + try: + cur.execute("drop type pypy_test_arraytype") + except oracle.DatabaseError: + pass + cur.execute("""\ + create type pypy_test_objtype as object ( + numbercol number, + stringcol varchar2(60), + datecol date); + """) + cur.execute("""\ + create type pypy_test_arraytype as varray(10) of number; + """) + cur.execute("""\ + create table pypy_test_objtable ( + objcol pypy_test_objtype, + arraycol pypy_test_arraytype) + """) + cur.execute("""\ + insert into pypy_test_objtable values ( + pypy_test_objtype(1, 'someText', + to_date(20070306, 'YYYYMMDD')), + pypy_test_arraytype(5, 10, null, 20)) + """) + + cur.execute("select objcol, arraycol from pypy_test_objtable") + objValue, arrayValue = cur.fetchone() + assert objValue.type.schema == self.cnx.username.upper() + assert objValue.type.name == "PYPY_TEST_OBJTYPE" + assert objValue.type.attributes[0].name == "NUMBERCOL" + assert isinstance(arrayValue, list) + assert arrayValue == [5, 10, None, 20] + assert objValue.NUMBERCOL == 1 + assert objValue.STRINGCOL == "someText" + assert objValue.DATECOL == datetime.datetime(2007, 03, 06) + raises(AttributeError, getattr, objValue, 'OTHER') From arigo at codespeak.net Tue Mar 9 16:33:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 16:33:52 +0100 (CET) Subject: [pypy-svn] r71962 - pypy/trunk/pypy/lib Message-ID: <20100309153352.3455A36C202@codespeak.net> Author: arigo Date: Tue Mar 9 16:33:50 2010 New Revision: 71962 Removed: pypy/trunk/pypy/lib/sqlite3 Log: Delete the symlink. This comes together with the next checkin. From arigo at codespeak.net Tue Mar 9 16:34:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 16:34:19 +0100 (CET) Subject: [pypy-svn] r71963 - pypy/trunk/pypy/lib Message-ID: <20100309153419.98C03282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 16:34:18 2010 New Revision: 71963 Modified: pypy/trunk/pypy/lib/ (props changed) Log: Remove the need for the symlink 'sqlite3', by renaming pysqlite2 to sqlite3. No-one should import pysqlite2 any more, as the name sqlite3 is present from Python 2.5. From arigo at codespeak.net Tue Mar 9 16:39:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 16:39:11 +0100 (CET) Subject: [pypy-svn] r71964 - pypy/release/1.2.x/pypy/lib Message-ID: <20100309153911.321EF282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 16:39:09 2010 New Revision: 71964 Removed: pypy/release/1.2.x/pypy/lib/sqlite3 Modified: pypy/release/1.2.x/pypy/lib/ (props changed) Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71961:71963 From fijal at codespeak.net Tue Mar 9 16:55:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 16:55:10 +0100 (CET) Subject: [pypy-svn] r71965 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100309155510.52E7D282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 16:55:08 2010 New Revision: 71965 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Log: apparently GenericArray is not needed Modified: pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/dtype.py Tue Mar 9 16:55:08 2010 @@ -14,6 +14,7 @@ return unwrap_float(space, space.float(w_x)) from pypy.rlib.rarithmetic import r_singlefloat as float32 + def unwrap_float32(space, w_x): return float32(space.float_w(w_x)) def coerce_float32(space, w_x): Modified: pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/ndarray.py Tue Mar 9 16:55:08 2010 @@ -6,7 +6,6 @@ from pypy.rlib.debug import make_sure_not_resized from pypy.module.micronumpy.sdarray import sdresult -from pypy.module.micronumpy.sdarray import GenericArray from pypy.module.micronumpy.mdarray import mdresult Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Tue Mar 9 16:55:08 2010 @@ -289,6 +289,5 @@ IntArray = create_sdarray(int, unwrap_int, coerce_int) FloatArray = create_sdarray(float, unwrap_float, coerce_float) -GenericArray = None sdresult = create_factory({'i': IntArray, 'd': FloatArray}) From arigo at codespeak.net Tue Mar 9 16:58:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 16:58:26 +0100 (CET) Subject: [pypy-svn] r71966 - in pypy/trunk/pypy/translator/platform: . test Message-ID: <20100309155826.CA3E0282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 16:58:25 2010 New Revision: 71966 Modified: pypy/trunk/pypy/translator/platform/posix.py pypy/trunk/pypy/translator/platform/test/test_posix.py Log: Test and fix: mirror eci.link_files into the Makefile. Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Tue Mar 9 16:58:25 2010 @@ -91,13 +91,14 @@ ('LDFLAGS', self.link_flags + list(eci.link_extra)), ('CC', self.cc), ('CC_LINK', eci.use_cpp_linker and 'g++' or '$(CC)'), + ('LINKFILES', eci.link_files), ] for args in definitions: m.definition(*args) rules = [ ('all', '$(DEFAULT_TARGET)', []), - ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) $(LINKFILES)'), ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), ] Modified: pypy/trunk/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/test/test_posix.py (original) +++ pypy/trunk/pypy/translator/platform/test/test_posix.py Tue Mar 9 16:58:25 2010 @@ -41,7 +41,14 @@ if self.strict_on_stderr: assert res.err == '' assert res.returncode == 0 - + + def test_link_files(self): + tmpdir = udir.join('link_files' + self.__class__.__name__).ensure(dir=1) + eci = ExternalCompilationInfo(link_files=['/foo/bar.a']) + mk = self.platform.gen_makefile(['blip.c'], eci, path=tmpdir) + mk.write() + assert 'LINKFILES = /foo/bar.a' in tmpdir.join('Makefile').read() + class TestMaemo(TestMakefile): strict_on_stderr = False From fijal at codespeak.net Tue Mar 9 17:03:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 17:03:52 +0100 (CET) Subject: [pypy-svn] r71967 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100309160352.F34CA282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 17:03:51 2010 New Revision: 71967 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Log: simplify sdarray Modified: pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/sdarray.py Tue Mar 9 17:03:51 2010 @@ -183,8 +183,7 @@ def descr_setitem(self, w_index, w_value): space = self.space - if space.is_true(space.isinstance(w_index, space.w_slice)): - assert isinstance(w_index, W_SliceObject) + if isinstance(w_index, W_SliceObject): start, stop, step, slen = w_index.indices4(space, self.len()) try: space.iter(w_value) From fijal at codespeak.net Tue Mar 9 17:04:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 17:04:06 +0100 (CET) Subject: [pypy-svn] r71968 - pypy/branch/micronumpy/pypy/module/micronumpy/test Message-ID: <20100309160406.1AA23282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 17:04:04 2010 New Revision: 71968 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Log: unskip and fix test Modified: pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/test/test_numpy.py Tue Mar 9 17:04:04 2010 @@ -276,7 +276,6 @@ assert ar[i, j] == i*3+j def test_get_set_slices(self): - skip("We don't raise exceptions like CPython NumPy.") from numpy import array gen_array = self.gen_array compare = self.compare @@ -301,7 +300,7 @@ #setitem ar[2] = 3 assert ar[2, 0] == ar[2, 1] == ar[2, 2] == 3 - ar[2:3] = [7] + ar[2:3, 0] = [7] ar[2] = [0, 1, 2] assert compare(ar[0], ar[2]) assert compare(ar[..., 0], [0, 3, 0]) From fijal at codespeak.net Tue Mar 9 17:05:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 17:05:26 +0100 (CET) Subject: [pypy-svn] r71969 - pypy/branch/micronumpy/pypy/module/micronumpy Message-ID: <20100309160526.5AF97282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 17:05:25 2010 New Revision: 71969 Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Log: Add an xxx for untested code Modified: pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py ============================================================================== --- pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py (original) +++ pypy/branch/micronumpy/pypy/module/micronumpy/mdarray.py Tue Mar 9 17:05:25 2010 @@ -327,6 +327,7 @@ if len(regions) == 0: return l = len(arr.storage) if lslice > l: #long slice + xxx iters = lslice // l assert lslice == l * iters for start in regions: From fijal at codespeak.net Tue Mar 9 17:56:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 17:56:40 +0100 (CET) Subject: [pypy-svn] r71972 - in pypy/trunk/pypy/module: imp pypyjit pypyjit/test sys Message-ID: <20100309165640.16135282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 17:56:39 2010 New Revision: 71972 Modified: pypy/trunk/pypy/module/imp/importing.py pypy/trunk/pypy/module/pypyjit/policy.py pypy/trunk/pypy/module/pypyjit/test/test_policy.py pypy/trunk/pypy/module/sys/state.py Log: (fijal, benjamin) Merge import-fiddle branch. This branch exposes to the JIT the part of importing that checks if module is already in sys.modules and if so, can constant-fold away this checks. Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Tue Mar 9 17:56:39 2010 @@ -9,7 +9,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root, ObjSpace from pypy.interpreter.eval import Code -from pypy.rlib import streamio +from pypy.rlib import streamio, jit from pypy.rlib.streamio import StreamErrors from pypy.rlib.rarithmetic import intmask from pypy.rlib.objectmodel import we_are_translated @@ -80,6 +80,9 @@ def check_sys_modules(space, w_modulename): return space.finditem(space.sys.get('modules'), w_modulename) +def check_sys_modules_w(space, modulename): + return space.finditem_str(space.sys.get('modules'), modulename) + def importhook(space, modulename, w_globals=None, w_locals=None, w_fromlist=None, level=-1): space.timer.start_name("importhook", modulename) @@ -89,8 +92,15 @@ space.wrap("Empty module name")) w = space.wrap - ctxt_name = None - if w_globals is not None and not space.is_w(w_globals, space.w_None): + if w_fromlist is not None and space.is_true(w_fromlist): + fromlist_w = space.fixedview(w_fromlist) + else: + fromlist_w = None + + rel_modulename = None + if (level != 0 and + w_globals is not None and + not space.is_w(w_globals, space.w_None)): ctxt_w_name = space.finditem(w_globals, w('__name__')) ctxt_w_path = space.finditem(w_globals, w('__path__')) if ctxt_w_name is not None: @@ -99,62 +109,97 @@ except OperationError, e: if not e.match(space, space.w_TypeError): raise - else: - ctxt_w_path = None - - rel_modulename = None - if ctxt_name is not None: - if level == 0: - baselevel = 0 - rel_modulename = modulename - else: - ctxt_name_prefix_parts = ctxt_name.split('.') - if level > 0: - n = len(ctxt_name_prefix_parts)-level+1 - assert n>=0 - ctxt_name_prefix_parts = ctxt_name_prefix_parts[:n] - if ctxt_w_path is None: # plain module - ctxt_name_prefix_parts.pop() - if ctxt_name_prefix_parts: - rel_modulename = '.'.join(ctxt_name_prefix_parts) - if modulename: - rel_modulename += '.' + modulename - baselevel = len(ctxt_name_prefix_parts) - - if rel_modulename is not None: - w_mod = check_sys_modules(space, w(rel_modulename)) - if (w_mod is None or - not space.is_w(w_mod, space.w_None)): - - w_mod = absolute_import(space, rel_modulename, - baselevel, - w_fromlist, tentative=1) - if w_mod is not None: - space.timer.stop_name("importhook", modulename) - return w_mod else: - rel_modulename = None + ctxt_name_prefix_parts = ctxt_name.split('.') + if level > 0: + n = len(ctxt_name_prefix_parts)-level+1 + assert n>=0 + ctxt_name_prefix_parts = ctxt_name_prefix_parts[:n] + if ctxt_w_path is None: # plain module + ctxt_name_prefix_parts.pop() + if ctxt_name_prefix_parts: + rel_modulename = '.'.join(ctxt_name_prefix_parts) + if modulename: + rel_modulename += '.' + modulename + baselevel = len(ctxt_name_prefix_parts) + if rel_modulename is not None: + w_mod = check_sys_modules(space, w(rel_modulename)) + if (w_mod is None or + not space.is_w(w_mod, space.w_None)): + w_mod = absolute_import(space, rel_modulename, + baselevel, + fromlist_w, tentative=1) + if w_mod is not None: + space.timer.stop_name("importhook", modulename) + return w_mod + else: + rel_modulename = None if level > 0: msg = "Attempted relative import in non-package" raise OperationError(space.w_ValueError, w(msg)) - w_mod = absolute_import(space, modulename, 0, w_fromlist, tentative=0) + w_mod = absolute_import_try(space, modulename, 0, fromlist_w) + if w_mod is None and not space.is_w(w_mod, space.w_None): + w_mod = absolute_import(space, modulename, 0, fromlist_w, tentative=0) if rel_modulename is not None: - space.setitem(space.sys.get('modules'), w(rel_modulename),space.w_None) + space.setitem(space.sys.get('modules'), w(rel_modulename), space.w_None) space.timer.stop_name("importhook", modulename) return w_mod # importhook.unwrap_spec = [ObjSpace, str, W_Root, W_Root, W_Root, int] -def absolute_import(space, modulename, baselevel, w_fromlist, tentative): + at jit.dont_look_inside +def absolute_import(space, modulename, baselevel, fromlist_w, tentative): lock = getimportlock(space) lock.acquire_lock() try: return _absolute_import(space, modulename, baselevel, - w_fromlist, tentative) + fromlist_w, tentative) finally: lock.release_lock() -def _absolute_import(space, modulename, baselevel, w_fromlist, tentative): + at jit.unroll_safe +def absolute_import_try(space, modulename, baselevel, fromlist_w): + """ Only look up sys.modules, not actually try to load anything + """ + w_path = None + last_dot = 0 + if '.' not in modulename: + w_mod = check_sys_modules_w(space, modulename) + first = w_mod + if fromlist_w is not None and w_mod is not None: + w_path = try_getattr(space, w_mod, space.wrap('__path__')) + else: + level = 0 + first = None + while last_dot != -1: + assert last_dot >= 0 # bah + last_dot = modulename.find('.', last_dot + 1) + if last_dot == -1: + w_mod = check_sys_modules_w(space, modulename) + else: + assert last_dot >= 0 + w_mod = check_sys_modules_w(space, modulename[:last_dot]) + if w_mod is None or space.is_w(w_mod, space.w_None): + return None + if level == baselevel: + first = w_mod + if fromlist_w is not None: + w_path = try_getattr(space, w_mod, space.wrap('__path__')) + level += 1 + if fromlist_w is not None: + if w_path is not None: + if len(fromlist_w) == 1 and space.eq_w(fromlist_w[0], + space.wrap('*')): + w_all = try_getattr(space, w_mod, space.wrap('__all__')) + if w_all is not None: + fromlist_w = space.fixedview(w_all) + for w_name in fromlist_w: + if try_getattr(space, w_mod, w_name) is None: + return None + return w_mod + return first + +def _absolute_import(space, modulename, baselevel, fromlist_w, tentative): w = space.wrap w_mod = None @@ -178,13 +223,12 @@ w_path = try_getattr(space, w_mod, w('__path__')) level += 1 - if w_fromlist is not None and space.is_true(w_fromlist): + if fromlist_w is not None: if w_path is not None: - fromlist_w = space.unpackiterable(w_fromlist) if len(fromlist_w) == 1 and space.eq_w(fromlist_w[0],w('*')): w_all = try_getattr(space, w_mod, w('__all__')) if w_all is not None: - fromlist_w = space.unpackiterable(w_all) + fromlist_w = space.fixedview(w_all) for w_name in fromlist_w: if try_getattr(space, w_mod, w_name) is None: load_part(space, w_path, prefix, space.str_w(w_name), w_mod, @@ -301,6 +345,7 @@ if pkgdir is not None: space.setattr(w_mod, w('__path__'), space.newlist([w(pkgdir)])) + at jit.dont_look_inside def load_module(space, w_modulename, find_info, reuse=False): if find_info is None: return @@ -384,6 +429,7 @@ msg = "No module named %s" raise operationerrfmt(space.w_ImportError, msg, modulename) + at jit.dont_look_inside def reload(space, w_module): """Reload the module. The module must have been successfully imported before.""" @@ -581,6 +627,7 @@ code_w.exec_code(space, w_dict, w_dict) + at jit.dont_look_inside def load_source_module(space, w_modulename, w_mod, pathname, source, write_pyc=True): """ @@ -679,6 +726,7 @@ "Non-code object in %s", cpathname) return pycode + at jit.dont_look_inside def load_compiled_module(space, w_modulename, w_mod, cpathname, magic, timestamp, source): """ Modified: pypy/trunk/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/policy.py Tue Mar 9 17:56:39 2010 @@ -8,10 +8,12 @@ modname == '__builtin__.interp_classobj' or modname == '__builtin__.functional'): return True - + if modname == 'sys.state': + return True if '.' in modname: modname, _ = modname.split('.', 1) - if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions']: + if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', + 'imp']: return True return False Modified: pypy/trunk/pypy/module/pypyjit/test/test_policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_policy.py Tue Mar 9 17:56:39 2010 @@ -32,7 +32,7 @@ assert pypypolicy.look_inside_pypy_module('__builtin__.abstractinst') assert pypypolicy.look_inside_pypy_module('__builtin__.functional') assert pypypolicy.look_inside_pypy_module('exceptions.interp_exceptions') - for modname in 'pypyjit', 'signal', 'micronumpy', 'math': + for modname in 'pypyjit', 'signal', 'micronumpy', 'math', 'imp': assert pypypolicy.look_inside_pypy_module(modname) assert pypypolicy.look_inside_pypy_module(modname + '.foo') @@ -42,3 +42,4 @@ def test_module_with_stuff_in_init(): from pypy.module.sys import Module assert not pypypolicy.look_inside_function(Module.getdictvalue.im_func) + Modified: pypy/trunk/pypy/module/sys/state.py ============================================================================== --- pypy/trunk/pypy/module/sys/state.py (original) +++ pypy/trunk/pypy/module/sys/state.py Tue Mar 9 17:56:39 2010 @@ -14,7 +14,7 @@ def __init__(self, space): self.space = space - self.w_modules = space.newdict() + self.w_modules = space.newdict(module=True) self.w_warnoptions = space.newlist([]) self.w_argv = space.newlist([]) From fijal at codespeak.net Tue Mar 9 17:57:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 17:57:04 +0100 (CET) Subject: [pypy-svn] r71973 - pypy/branch/import-fiddle Message-ID: <20100309165704.E4C27282BD5@codespeak.net> Author: fijal Date: Tue Mar 9 17:57:03 2010 New Revision: 71973 Removed: pypy/branch/import-fiddle/ Log: remove merged branch From arigo at codespeak.net Tue Mar 9 17:58:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 17:58:45 +0100 (CET) Subject: [pypy-svn] r71974 - in pypy/trunk/pypy/lib/ctypes_config_cache: . test Message-ID: <20100309165845.C5A41282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 17:58:44 2010 New Revision: 71974 Modified: pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py pypy/trunk/pypy/lib/ctypes_config_cache/test/test_cache.py Log: Test and fix: CHAR_MAX is actually coming from limits.h. Modified: pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/trunk/pypy/lib/ctypes_config_cache/locale.ctc.py Tue Mar 9 17:58:44 2010 @@ -22,7 +22,8 @@ ] class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) + _compilation_info_ = ExternalCompilationInfo(includes=['limits.h', + 'locale.h']) for key in _CONSTANTS: setattr(LocaleConfigure, key, DefinedConstantInteger(key)) @@ -34,7 +35,7 @@ # ____________________________________________________________ -eci = ExternalCompilationInfo(includes=['langinfo.h']) +eci = ExternalCompilationInfo(includes=['locale.h', 'langinfo.h']) HAS_LANGINFO = check_eci(eci) if HAS_LANGINFO: Modified: pypy/trunk/pypy/lib/ctypes_config_cache/test/test_cache.py ============================================================================== --- pypy/trunk/pypy/lib/ctypes_config_cache/test/test_cache.py (original) +++ pypy/trunk/pypy/lib/ctypes_config_cache/test/test_cache.py Tue Mar 9 17:58:44 2010 @@ -38,3 +38,8 @@ def test_pyexpat(): d = run('pyexpat.ctc.py', '_pyexpat_cache.py') assert 'XML_COMBINED_VERSION' in d + +def test_locale(): + d = run('locale.ctc.py', '_locale_cache.py') + assert 'LC_ALL' in d + assert 'CHAR_MAX' in d From arigo at codespeak.net Tue Mar 9 18:03:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 18:03:27 +0100 (CET) Subject: [pypy-svn] r71975 - in pypy/release/1.2.x/pypy/translator/platform: . test Message-ID: <20100309170327.11C90282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 18:03:26 2010 New Revision: 71975 Modified: pypy/release/1.2.x/pypy/translator/platform/posix.py pypy/release/1.2.x/pypy/translator/platform/test/test_posix.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71965:71966 Modified: pypy/release/1.2.x/pypy/translator/platform/posix.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/platform/posix.py (original) +++ pypy/release/1.2.x/pypy/translator/platform/posix.py Tue Mar 9 18:03:26 2010 @@ -91,13 +91,14 @@ ('LDFLAGS', self.link_flags + list(eci.link_extra)), ('CC', self.cc), ('CC_LINK', eci.use_cpp_linker and 'g++' or '$(CC)'), + ('LINKFILES', eci.link_files), ] for args in definitions: m.definition(*args) rules = [ ('all', '$(DEFAULT_TARGET)', []), - ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS)'), + ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) $(LINKFILES)'), ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), ] Modified: pypy/release/1.2.x/pypy/translator/platform/test/test_posix.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/platform/test/test_posix.py (original) +++ pypy/release/1.2.x/pypy/translator/platform/test/test_posix.py Tue Mar 9 18:03:26 2010 @@ -41,7 +41,14 @@ if self.strict_on_stderr: assert res.err == '' assert res.returncode == 0 - + + def test_link_files(self): + tmpdir = udir.join('link_files' + self.__class__.__name__).ensure(dir=1) + eci = ExternalCompilationInfo(link_files=['/foo/bar.a']) + mk = self.platform.gen_makefile(['blip.c'], eci, path=tmpdir) + mk.write() + assert 'LINKFILES = /foo/bar.a' in tmpdir.join('Makefile').read() + class TestMaemo(TestMakefile): strict_on_stderr = False From arigo at codespeak.net Tue Mar 9 18:04:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Mar 2010 18:04:00 +0100 (CET) Subject: [pypy-svn] r71976 - in pypy/release/1.2.x/pypy/lib/ctypes_config_cache: . test Message-ID: <20100309170400.68176282BD5@codespeak.net> Author: arigo Date: Tue Mar 9 18:03:59 2010 New Revision: 71976 Modified: pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py pypy/release/1.2.x/pypy/lib/ctypes_config_cache/test/test_cache.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r71973:71974 Modified: pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py (original) +++ pypy/release/1.2.x/pypy/lib/ctypes_config_cache/locale.ctc.py Tue Mar 9 18:03:59 2010 @@ -22,7 +22,8 @@ ] class LocaleConfigure: - _compilation_info_ = ExternalCompilationInfo(includes=['locale.h']) + _compilation_info_ = ExternalCompilationInfo(includes=['limits.h', + 'locale.h']) for key in _CONSTANTS: setattr(LocaleConfigure, key, DefinedConstantInteger(key)) @@ -34,7 +35,7 @@ # ____________________________________________________________ -eci = ExternalCompilationInfo(includes=['langinfo.h']) +eci = ExternalCompilationInfo(includes=['locale.h', 'langinfo.h']) HAS_LANGINFO = check_eci(eci) if HAS_LANGINFO: Modified: pypy/release/1.2.x/pypy/lib/ctypes_config_cache/test/test_cache.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/ctypes_config_cache/test/test_cache.py (original) +++ pypy/release/1.2.x/pypy/lib/ctypes_config_cache/test/test_cache.py Tue Mar 9 18:03:59 2010 @@ -38,3 +38,8 @@ def test_pyexpat(): d = run('pyexpat.ctc.py', '_pyexpat_cache.py') assert 'XML_COMBINED_VERSION' in d + +def test_locale(): + d = run('locale.ctc.py', '_locale_cache.py') + assert 'LC_ALL' in d + assert 'CHAR_MAX' in d From getxsick at codespeak.net Tue Mar 9 18:13:38 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 9 Mar 2010 18:13:38 +0100 (CET) Subject: [pypy-svn] r71977 - pypy/build/ubuntu/debian Message-ID: <20100309171338.4959C282BD5@codespeak.net> Author: getxsick Date: Tue Mar 9 18:13:36 2010 New Revision: 71977 Modified: pypy/build/ubuntu/debian/rules Log: Update build rules. No need to install ctypes_configure anymore (see r71873). Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Tue Mar 9 18:13:36 2010 @@ -56,8 +56,6 @@ rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ - rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/ctypes_configure - cp -r ctypes_configure debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/ install-arch: dh_testdir From getxsick at codespeak.net Tue Mar 9 18:17:13 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 9 Mar 2010 18:17:13 +0100 (CET) Subject: [pypy-svn] r71978 - pypy/build/ubuntu/debian/manpages Message-ID: <20100309171713.BEB73282BD5@codespeak.net> Author: getxsick Date: Tue Mar 9 18:17:12 2010 New Revision: 71978 Modified: pypy/build/ubuntu/debian/manpages/dotviewer.1 pypy/build/ubuntu/debian/manpages/pypy.1 pypy/build/ubuntu/debian/manpages/rpycompile.1 pypy/build/ubuntu/debian/manpages/sshgraphserver.1 Log: update manpages Modified: pypy/build/ubuntu/debian/manpages/dotviewer.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/dotviewer.1 (original) +++ pypy/build/ubuntu/debian/manpages/dotviewer.1 Tue Mar 9 18:17:12 2010 @@ -12,7 +12,7 @@ manner. It's widely used by various PyPy's debugging tools, like JIT assembler viewer, flowgraph viewer etc. .SH SEE ALSO -.BR graphserver(1), sshgraphserver(1), pypy (1), +.BR sshgraphserver(1), pypy (1), .SH AUTHORS \fBPyPy\fP was written by the members of the PyPy project . .PP Modified: pypy/build/ubuntu/debian/manpages/pypy.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/pypy.1 (original) +++ pypy/build/ubuntu/debian/manpages/pypy.1 Tue Mar 9 18:17:12 2010 @@ -39,7 +39,7 @@ Print translation information about this PyPy executable. .TP .B \-\-jit debug=N -Set the verbosity of the jit (default: 0) +Set the verbosity of the jit (default: off) .TP .B \-\-jit inlining=N low-level JIT parameter (default: False) @@ -56,7 +56,7 @@ .B \-\-jit trace_limit=N low-level JIT parameter (default: 10000) .SH SEE ALSO -.BR rpycompile (1), dotviewer (1), graphserver(1), sshgraphserver(1), +.BR rpycompile (1), dotviewer (1), sshgraphserver(1), .SH AUTHORS \fBPyPy\fP was written by the members of the PyPy project . .PP Modified: pypy/build/ubuntu/debian/manpages/rpycompile.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/rpycompile.1 (original) +++ pypy/build/ubuntu/debian/manpages/rpycompile.1 Tue Mar 9 18:17:12 2010 @@ -10,7 +10,7 @@ .TP To see the full list, please see the documentation or \fB--help\fP option. .SH SEE ALSO -.BR pypy (1), +.BR pypy (1), dotviewer(1), sshgraphserver(1), .SH AUTHORS \fBPyPy\fP was written by the members of the PyPy project . .PP Modified: pypy/build/ubuntu/debian/manpages/sshgraphserver.1 ============================================================================== --- pypy/build/ubuntu/debian/manpages/sshgraphserver.1 (original) +++ pypy/build/ubuntu/debian/manpages/sshgraphserver.1 Tue Mar 9 18:17:12 2010 @@ -14,7 +14,7 @@ programs using the dotviewer library as long as they run on 'hostname' under the same username as the one sshgraphserver logs as. .SH SEE ALSO -.BR graphserver (1), dotviewer (1), pypy (1), +.BR dotviewer (1), pypy (1), .SH AUTHORS \fBPyPy\fP was written by the members of the PyPy project . .PP From fijal at codespeak.net Tue Mar 9 18:25:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:25:54 +0100 (CET) Subject: [pypy-svn] r71979 - in pypy/extradoc/pypy.org: . css image js Message-ID: <20100309172554.2DA89282BD7@codespeak.net> Author: fijal Date: Tue Mar 9 18:25:52 2010 New Revision: 71979 Added: pypy/extradoc/pypy.org/archive.html pypy/extradoc/pypy.org/compat.html pypy/extradoc/pypy.org/css/ pypy/extradoc/pypy.org/css/site.css pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/image/ pypy/extradoc/pypy.org/image/header-background.png (contents, props changed) pypy/extradoc/pypy.org/image/pypy-logo.png (contents, props changed) pypy/extradoc/pypy.org/js/ pypy/extradoc/pypy.org/js/detect.js pypy/extradoc/pypy.org/more.html pypy/extradoc/pypy.org/sandbox.html Modified: pypy/extradoc/pypy.org/ (props changed) pypy/extradoc/pypy.org/index.html Log: Try to import new stuff for pypy.org, let's see... Added: pypy/extradoc/pypy.org/archive.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/archive.html Tue Mar 9 18:25:52 2010 @@ -0,0 +1,59 @@ + + + + PyPy + + + + + + + + + + + + + + + +
+ +
+
+ +
    +
+
+ +
    +
+
+
+
+ + \ No newline at end of file Added: pypy/extradoc/pypy.org/compat.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/compat.html Tue Mar 9 18:25:52 2010 @@ -0,0 +1,128 @@ + + + + PyPy :: Python compatibility + + + + + + + + + + + + + + + +
+ +
+
+
+

Python compatibility

+

PyPy implements Python language version 2.5. It supports all of the core +language, passing Python test suite (with minor modifications that were +already accepted in main python in newer versions). It supports most +of commonly used Python standard library modules, list below.

+

PyPy does not support CPython C API, which means that third party +libraries for python, written in C, will not work.

+

Standard library modules supported by PyPy, in alphabetical order:

+
    +
  • __builtin__ __pypy__ _codecs _lsprof _minimal_curses _random _rawffi _socket _sre _weakref bz2 cStringIO crypt errno exceptions fcntl gc itertools marshal math md5 mmap operator parser posix pyexpat select sha signal struct symbol sys termios thread time token unicodedata zipimport zlib
  • +
+

Supported, but written in pure-python:

+
    +
  • array binascii cPickle cmath collections ctypes datetime functools grp md5 pwd pyexpat sha sqlite3 syslog
  • +
+

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

+

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

+
    +
  • ctypes
  • +
  • django (without any DB but sqlite)
  • +
  • twisted (without ssl support)
  • +
  • pylons
  • +
  • divmod's nevow
  • +
  • pyglet
  • +
+

Known differencies that are not going to be fixed:

+
    +
  • PyPy does not support refcounting semantics. The code below +won't fill the file immediately, but only after a certain period +of time, when the GC will collect:

    +
    +open("filename", "w").write("stuff")
    +
    +

    The proper fix is:

    +
    +f = open("filename", "w")
    +f.write("stuff")
    +f.close()
    +
    +
  • +
  • We don't support certain attributes that were decided to be +implementation-dependent. For example gc.get_referrers. gc.enable +and gc.disable are supported, but they don't enable and disable GC, +but instead enable and disable running of finalizers.

    +
  • +
  • You can't attach a __del__ method to a class after its creation.

    +
  • +
  • You can't store non-string keys in type objects. Example:

    +
    +class A(object):
    +    locals()[42] = 3
    +
    +

    won't work.

    +
  • +
+
+ +
+
+
+ + \ No newline at end of file Added: pypy/extradoc/pypy.org/css/site.css ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/css/site.css Tue Mar 9 18:25:52 2010 @@ -0,0 +1,1352 @@ +/* No Copyright (-) 2010 The Ampify Authors. This file is under the */ +/* Public Domain license that can be found in the root LICENSE file. */ + +/* Element styles */ + +* { + margin: 0; + padding: 0; +} + +html { + height: 100%; +} + +body { + background-color: #efefef; + background-repeat: repeat; + font: 90%/1em 'Lucida Grande', 'Lucida Sans Unicode', Optima, Verdana, sans-serif; + height: 100%; + width: 100%; +} + +a, a:visited, a:hover, a:active, a:hover { + color: blue; + text-decoration: underline; +} + +a:hover { + text-decoration: none; +} + +a.promote-fb, a.promote-fb:active, a.promote-fb:hover, a.promote-fb:visited { + background: url(http://static.ampify.it/gfx.share-facebook-sprite.png) no-repeat; + color: transparent; + display: block; + float: left; + height: 22px; + margin: 0 16px 0 0px; + outline; none; + overflow: hidden; + position: relative; + text-indent: 9999px !important; + top: -2px; + vertical-align: middle; + width: 146px; +} + +a.promote-fb:hover { + background-position: 0 -22px; +} + +a.promote-fb:active { + background-position: 0 -44px; +} + +blockquote, p, dl, h1, h2, h3, h4, h5, h6, ol, ul { + padding-top: 0.5em; + padding-bottom: 0.5em; +} + +code, .literal { + background-color: #f0f0f0; + border: 1px solid #dadada; + padding: 1px 3px; + font-family: Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; +} + +dl, ol, ul { + padding-left: 20px; +} + +h1 { + font-size: 2.25em; +} + +h1, h2 { + color: #c32528; + font-family: "museo-1", "museo-2", Verdana; + letter-spacing: 1px; + text-shadow: #eee 2px 2px 3px; +} + +img { + border: 0; +} + +label, input, select, textarea { + cursor: pointer; +} + +pre { + background-color: #fff; + border: 1px solid #cacaca; + color: #101010; + font: 12px/1.4em Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; + overflow: auto; + padding: 7px 0 8px 7px; + margin: 10px 30px 0 30px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0px 0px 7px #cacaca; +} + +pre.ascii-art { + line-height: 1em; + overflow: visible; +} + +pre code { + background-color: transparent; + border: 0; + padding: 0; +} + +select { + max-width: 200px; +} + + +strong { + font-family: Museo, Verdana; + font-size: 1.1em; +} + +table, table.docutils { + border: 0; + border-collapse: collapse; + margin: 0 auto; + text-align: left; +} + +table.docutils { + margin: 5px 40px 10px 30px; +} + +/* +table a { + text-decoration: none; +} +*/ + +th { + border-bottom: 2px solid #808096; + padding: 8px; +} + +table.docutils td { + border-bottom: 1px solid #ccc; + padding: 9px 8px 8px 8px; +} + +ul { + list-style-type: circle; +} + +/* ID styles */ + +#body { + background-color: #fff; + border-radius: 15px; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + padding: 5px; +} + +#body-inner { + margin: 0 auto; + padding: 10px 20px; + width: 950px; +} + +#body-outer { + height: 100%; +} + +body > #body-outer { + height: auto; + min-height: 100%; +} + +#content { + line-height: 1.55em; +} + +#footer-espians { + margin: 0 auto; + text-align: center; +} + +#footer { + background-color: #161616; + background-image: url(http://static.ampify.it/gfx.footer-background.png); + background-position: top left; + background-repeat: repeat-x; + clear: both; + color: #fff; + height: 50px; + margin-top: -200px; + position: relative; + text-align: center; + width: 100%; +} + +#footer-content { + margin: 0 auto; + padding-top: 15px; + text-align: center; +} + +#header { + width: 100%; + border-bottom: 1px dashed #9e9e9e; + margin-bottom: 10px; +} + +#logo { + float: left; +} + +#main { + float: left; + padding: 10px 30px 0 10px; + width: 630px; + line-height: 2em; + font-size: 0.9em; +} + +#main blockquote { + padding-left: 20px; +} + +#main h1 { + font-size: 1.5em; + padding-top: 20px; + padding-bottom: 0; +} + +#main h1.title { + font-size: 1.8em; + padding-top: 0; + padding-bottom: 10px; +} + +#main p { + padding-top: 10px; +} + +#main pre { + font-size: 14px; + font-family: "inconsolata-1", "inconsolata-2", Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; +} + +#main ul, #main ol { + padding-left: 35px; +} + +#main li { + padding-top: 5px; +} + +#sidebar { + float: left; + width: 270px; + font-size: 0.9em; + line-height: 1.6em; +} + +#sidebar a, #sidebar a:hover, #sidebar a:active, #sidebar a:visited { + text-decoration: none; +} + +#sidebar a:hover { + text-decoration: underline; +} + +#sidebar h3 { + text-align: right; + border-bottom: 1px solid #cacaca; + margin-bottom: 10px; +} + +#sidebar ul { + list-style-type: none; + padding: 0; + margin: 0; +} + +#sidebar li { + padding-bottom: 12px; +} + +#sidebar li div, .sidebar-text { + color: #6e6e6e; + font-size: 0.9em; +} + +#table-of-contents { + float: right; + margin: 10px 0 10px 20px; + border: 1px solid #cacaca; +} + +#table-of-contents .topic-title { + display: none; +} + +#table-of-contents ul { + padding: 0 20px 5px 20px; +} + +#main-support-page { + width: 540px; + margin: 0 auto; +} + +#main-support-page pre { + width: 350px; +} + +#menu ul { + list-style-type: none; + padding: 0; +} + +#menu ul li { + background-color: #fff; + float: left; + margin-left: 12px; + text-align: center; +} + +#menu a { + border-top: 2px solid #ccc; + color: #000; + display: block; + font-size: 18px; + padding-top: 6px; + padding-bottom: 8px; + text-decoration: none; +} + +#menu a.selected, #menu a.selected:hover { + background-color: #f6f6f6; + border-top: 2px solid #a9151b; +} + +#menu a:hover { + border-top: 2px solid #969696; +} + +#menu-follow { + float: right; +} + +#menu-follow div { + padding: 0 5px 5px 0; +} + +#menu-lang { + margin: 0 105px 0 20px; + float: left; + text-align: right; + width: 140px; +} + +#menu-lang select { + max-width: 120px; +} + +#menu-lang-form { + display: none; + margin-top: 5px; +} + +#menu-sub { + font-size: 1em; + padding-bottom: 10px; + text-align: center; +} + +.menu-sub-sep { + color: #9f9f9f; + padding: 2px; +} + +#spread-button { + background-color: #ffffff; + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + padding: 5px; +} + +/* Support site IDs */ + +#help-spread-the-word { + float: left; +} + +/* Class styles */ + +.absmiddle { + vertical-align: middle; +} + +.boxed { + border: 1px solid #cacaca; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0px 0px 7px #cacaca; +} + +.center { + text-align: center; +} + +/* clear utility classes */ + +.clear { + background-color: transparent; + border: 0px solid; + clear: both; + height: 0; + margin: 0; + padding: 0; + width: 0; +} + +.clear-left { + background-color: transparent; + border: 0px solid; + clear: left; + height: 0; + margin: 0; + padding: 0; + width: 0; +} + +.clear-right { + background-color: transparent; + border: 0px solid; + clear: right; + height: 0; + margin: 0; + padding: 0; + width: 0; +} + +/* clearfix */ + +.clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +.clearfix { + display: inline-block; +} + +/* Hides from IE-mac \*/ +* html .clearfix { + height: 1%; +} +.clearfix { + display: block; +} +/* End hide from IE-mac */ + +/* float utility classes */ + +.float-left { + float: left; + padding-bottom: 7px; + padding-right: 7px; +} + +.float-right { + float: right; + padding-bottom: 7px; + padding-left: 7px; +} + +/* footer classes */ + +.footer-follow { + margin: 0 45px 15px 0; + float: left; +} + +.footer-follow a { + color: #fff; + text-decoration: underline; + font-size: 10px; +} + +.footer-follow a:hover { + text-decoration: none; +} + +.footer-follow div { + white-space: nowrap; +} + +.footer-menu { + float: right; + margin: 17px 50px 0 0; + font-size: 10px; +} + +.footer-menu a { + color: #fff; + padding-left: 5px; + padding-right: 5px; +} + +.footer-text { + text-align: left; +} + +/* quoted blocks with attribution */ + +.quote { + background: transparent url(http://static.ampify.it/gfx.blockquote.gif) no-repeat 0 0; + padding: 6px 12px 0 40px; + color: #575757; + font-size: 22px; + line-height: 28px; +} + +.quote-attribution { + color: #575757; + font-size: 14px; + text-align: right; + padding: 10px 12px 10px 0; +} + +.quote-attribution a, .quote-attribution a:active, .quote-attribution a:visited { + color: #575757; + text-decoration: underline; +} + +.quote-attribution a:hover { + text-decoration: none; +} + +/* Source code syntax highlighting */ + +.syntax .c { color: #919191 } /* Comment */ +.syntax .cm { color: #919191 } /* Comment.Multiline */ +.syntax .cp { color: #919191 } /* Comment.Preproc */ +.syntax .cs { color: #919191 } /* Comment.Special */ +.syntax .c1 { color: #919191 } /* Comment.Single */ + +.syntax .err { color: #a61717; background-color: #e3d2d2 } /* Error */ + +.syntax .g { color: #101010 } /* Generic */ +.syntax .gd { color: #d22323 } /* Generic.Deleted */ +.syntax .ge { color: #101010; font-style: italic } /* Generic.Emph */ +.syntax .gh { color: #101010 } /* Generic.Heading */ +.syntax .gi { color: #589819 } /* Generic.Inserted */ +.syntax .go { color: #6a6a6a } /* Generic.Output */ +.syntax .gp { color: #6a6a6a } /* Generic.Prompt */ +.syntax .gr { color: #d22323 } /* Generic.Error */ +.syntax .gs { color: #101010 } /* Generic.Strong */ +.syntax .gt { color: #d22323 } /* Generic.Traceback */ +.syntax .gu { color: #101010 } /* Generic.Subheading */ + +.syntax .k { color: #c32528 } /* Keyword */ /* espian red */ +.syntax .k { color: #ff5600 } /* Keyword */ /* orangy */ +.syntax .kc { color: #ff5600 } /* Keyword.Constant */ +.syntax .kd { color: #ff5600 } /* Keyword.Declaration */ +.syntax .kd { color: #ff5600 } /* Keyword.Declaration */ +.syntax .kn { color: #ff5600 } /* Keyword */ +.syntax .kp { color: #ff5600 } /* Keyword.Pseudo */ +.syntax .kr { color: #ff5600 } /* Keyword.Reserved */ +.syntax .kt { color: #ff5600 } /* Keyword.Type */ + +.syntax .l { color: #101010 } /* Literal */ +.syntax .ld { color: #101010 } /* Literal.Date */ + +.syntax .m { color: #3677a9 } /* Literal.Number */ /* darkish pastely blue */ +.syntax .m { color: #00a33f } /* Literal.Number */ /* brightish green */ +.syntax .m { color: #1550a2 } /* Literal.Number */ /* darker blue */ +.syntax .m { color: #5d90cd } /* Literal.Number */ /* pastely blue */ +.syntax .mf { color: #5d90cd } /* Literal.Number.Float */ +.syntax .mh { color: #5d90cd } /* Literal.Number.Hex */ +.syntax .mi { color: #5d90cd } /* Literal.Number.Integer */ +.syntax .il { color: #5d90cd } /* Literal.Number.Integer.Long */ +.syntax .mo { color: #5d90cd } /* Literal.Number.Oct */ + +.syntax .bp { color: #a535ae } /* Name.Builtin.Pseudo */ +.syntax .n { color: #101010 } /* Name */ +.syntax .na { color: #bbbbbb } /* Name.Attribute */ +.syntax .nb { color: #bf78cc } /* Name.Builtin */ /* pastely purple */ +.syntax .nb { color: #af956f } /* Name.Builtin */ /* pastely light brown */ +.syntax .nb { color: #a535ae } /* Name.Builtin */ /* brightish pastely purple */ +.syntax .nc { color: #101010 } /* Name.Class */ +.syntax .nd { color: #6d8091 } /* Name.Decorator */ +.syntax .ne { color: #af956f } /* Name.Exception */ +.syntax .nf { color: #3677a9 } /* Name.Function */ +.syntax .nf { color: #1550a2 } /* Name.Function */ +.syntax .ni { color: #101010 } /* Name.Entity */ +.syntax .nl { color: #101010 } /* Name.Label */ +.syntax .nn { color: #101010 } /* Name.Namespace */ +.syntax .nn { color: #101010 } /* Name.Namespace */ +.syntax .no { color: #101010 } /* Name.Constant */ +.syntax .nx { color: #101010 } /* Name.Other */ +.syntax .nt { color: #6d8091 } /* Name.Tag */ +.syntax .nv { color: #101010 } /* Name.Variable */ +.syntax .vc { color: #101010 } /* Name.Variable.Class */ +.syntax .vg { color: #101010 } /* Name.Variable.Global */ +.syntax .vi { color: #101010 } /* Name.Variable.Instance */ +.syntax .py { color: #101010 } /* Name.Property */ + +.syntax .o { color: #ff5600 } /* Operator */ /* orangy */ +.syntax .o { color: #101010 } /* Operator */ +.syntax .ow { color: #101010 } /* Operator.Word */ + +.syntax .p { color: #101010 } /* Punctuation */ + +.syntax .s { color: #dd1144 } /* Literal.String */ /* darkish red */ +.syntax .s { color: #c32528 } /* Literal.String */ /* espian red */ +.syntax .s { color: #39946a } /* Literal.String */ /* pastely greeny */ +.syntax .s { color: #5d90cd } /* Literal.String */ /* pastely blue */ +.syntax .s { color: #00a33f } /* Literal.String */ /* brightish green */ +.syntax .sb { color: #00a33f } /* Literal.String.Backtick */ +.syntax .sc { color: #00a33f } /* Literal.String.Char */ +.syntax .sd { color: #00a33f } /* Literal.String.Doc */ +.syntax .se { color: #00a33f } /* Literal.String.Escape */ +.syntax .sh { color: #00a33f } /* Literal.String.Heredoc */ +.syntax .si { color: #00a33f } /* Literal.String.Interpol */ +.syntax .sr { color: #00a33f } /* Literal.String.Regex */ +.syntax .ss { color: #00a33f } /* Literal.String.Symbol */ +.syntax .sx { color: #00a33f } /* Literal.String.Other */ +.syntax .s1 { color: #00a33f } /* Literal.String.Single */ +.syntax .s2 { color: #00a33f } /* Literal.String.Double */ + +.syntax .w { color: #101010 } /* Text.Whitespace */ +.syntax .x { color: #101010 } /* Other */ + +.syntax.bash .nb { color: #101010 } +.syntax.bash .nv { color: #c32528 } + +.syntax.css .k { color: #606060 } +.syntax.css .nc { color: #c32528 } +.syntax.css .nf { color: #c32528 } +.syntax.css .nt { color: #c32528 } + +.syntax.rst .k { color: #5d90cd } +.syntax.rst .ow { color: #5d90cd } +.syntax.rst .p { color: #5d90cd } + +.syntax.yaml .l-Scalar-Plain { color: #5d90cd } +.syntax.yaml .p-Indicator { color: #101010 } + +/* classes for support pages */ + +.community-section { + margin: 10px auto 10px auto; + width: 500px; +} + +.community-section-heading { + font-size: 1.6em; + margin-top: 10px; +} + +.community-section-heading span { + background-color: #efd7d7; + line-height: 1.7em; +} + +.community-section-text { + line-height: 1.6em; + padding: 10px 0 0 50px; +} + +.support-page-banner { + font-size: 1.2em; + line-height: 1.6em; + margin: 20px 0; +} + +.support-page-banner-text { + background-color: #f0f0f0; +} + +/* classes for the main support page */ + +.promote { + margin: 5px 0 0px 26px; +} + +.promote-retweet { + margin-top: 2px; + float: left; +} + +.promote-yahoo-buzz { + margin: -2px 15px 0 0; + float: left; + padding-bottom: 5px; +} + +.promote-google-buzz, .promote-google-buzz:active, .promote-google-buzz:visited, .promote-google-buzz:hover { + background: url(http://static.ampify.it/icon.google-buzz.png) no-repeat 0 3px; + color: #666; + float: left; + font-size: 0.9em; + font-weight: bold; + margin-top: -2px; + padding: 0 10px 5px 20px; + text-decoration: none; +} + +.promote-google-buzz:hover { + text-decoration: underline; +} + +.share-text { + font-size: 18px; + line-height: 24px; + margin: 0px 0 12px 26px; + color: #aaa; +} + +/* thanks to mashable.com for these wonderful share icons + css!! thanks guys -- you rock!! */ + +ul.share-buttons { + line-height: normal; + margin: 12px 0 0 24px; + padding: 0; +} + +.share-buttons li { + display: inline; + float: left; + list-style-type: none; + margin: 0 18px 12px 0; + padding-top: 1px; +} + +.share-buttons a { + background: url(http://static.ampify.it/gfx.mashable-syndication.gif) no-repeat; + color: #575757; + display: block; + font-size: 7px; + height: 14px; + overflow: hidden; + padding: 33px 0 0; + text-align: center; + text-decoration: none; + white-space: nowrap; + width: 46px; +} + +.share-buttons a:hover { + text-decoration:none; +} + +.share-buttons .delicious a { + background-position: -138px 0; +} + +.share-buttons .delicious a:hover { + background-position: -138px -47px; +} + +.share-buttons .digg a { + background-position: 0 0; +} + +.share-buttons .digg a:hover { + background-position: 0 -47px; +} + +.share-buttons .facebook a { + background-position: -184px 0; +} + +.share-buttons .facebook a:hover { + background-position: -184px -47px; +} + +.share-buttons .google a { + background-position: -276px 0; +} + +.share-buttons .google a:hover { + background-position: -276px -47px; +} + +.share-buttons .myspace a { + background-position: -230px 0; +} + +.share-buttons .myspace a:hover { + background-position: -230px -47px; +} + +.share-buttons .reddit a { + background-position: -414px 0; +} + +.share-buttons .reddit a:hover { + background-position: -414px -47px; +} + +.share-buttons .sharethis a { + background-position: -460px 0; +} + +.share-buttons .sharethis a:hover { + background-position: -460px -47px; +} + +.share-buttons .stumbleupon a { + background-position: -92px 0; +} + +.share-buttons .stumbleupon a:hover { + background-position: -92px -47px; +} + +.share-buttons .technorati a { + background-position: -322px 0; +} + +.share-buttons .technorati a:hover { + background-position: -322px -47px; +} + +.share-buttons .twitter a { + background-position: -46px 0; +} + +.share-buttons .twitter a:hover { + background-position: -46px -47px; +} + +.share-buttons .yahoo a { + background-position: -368px 0; +} + +.share-buttons .yahoo a:hover { + background-position: -368px -47px; +} + +/* Unsorted */ + +.columns { + max-width: 940px; + width: 940px; +} + +.column, .column-last { + float: left; + /* + height: 180px; + */ + padding: 0 10px 0 0; + position: relative; + width: 227px; +} + +.column-last { + padding: 0 0 0 0; +} + +.column-text { + font-size: 12px; + line-height: 18px; + margin: 10px 0 20px 15px; +} + +.column-footer { + background-image: url(bottom.gif); + background-repeat: no-repeat; + background-color: transparent; +/* + background-attachment: scroll; + */ +} + +.column-left { + border-right: 0px solid #f00; + float: left; + width: 455px; +} + +.column-left-text { + font-size: 12px; + line-height: 18px; + margin-left: 12px; +} + +.column-right { + float: right; + width: 485px; +} + +.follow { + display: block; + list-style-type: none; + margin: 12px 0px 0px 24px; + padding: 0px; + text-align: center; +} + +.follow li { + float: left; + display: block; + margin-right: 30px; + margin-bottom: 18px; +} + +.follow a { + color: #575757; + display: block; + font-size: 10px; + margin-top: 7px; + text-decoration: underline; + text-decoration: none; + font-weight: bold; +} + +.follow a:hover { + text-decoration: none; +} + +.get-left { + float: left; + width: 230px; + margin-right: 12px; + font-weight: bold; +} + +.get-right { + float: right; + width: 230px; + margin-right: 12px; + font-weight: bold; +} + +.get-item { + border: 1px solid #ccc; + border-radius: 15px; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + margin-top: 10px; + font-weight: normal; + margin: 12px 0 12px 0; + padding: 10px; +} + +.get-item img { + float: left; + margin-right: 5px; + padding-top: 3px; + vertical-align: middle; +} + +.headline { + margin-bottom: 10px; + text-align: center; + line-height: 36px; +} + +.headline-text { + background-color: #f0f0f0; + font-size: 20px; +} + +.headline-text-small { + background-color: #f0f0f0; + font-size: 20px; +} + +.lede { + background-color: #dfdfdf; +} + +.link { + font-size: 16px; +} + +.oneoff { + margin: 12px 12px 12px 0; + font-size: 14px; + line-height: 20px; + border-top: 1px solid #ccc; + border-bottom: 1px solid #ccc; + padding: 12px 0 12px 0; +} + +.optional { + color: #666; + font-size: 9px; + vertical-align: super; +} + +/* other */ + +#callout { + background-color: #fff; + margin-bottom: 10px; +/* + border-bottom-left-radius: 15px; + border-bottom-right-radius: 15px; + -moz-border-radius-bottomleft: 15px; + -moz-border-radius-bottomright: 15px; + -webkit-border-bottom-left-radius: 15px; + -webkit-border-bottom-right-radius: 15px; +*/ + padding: 10px; +} + +#feature { + float: right; +} + +#supporter-form { + font-size: 14px; + line-height: 26px; + margin: 8px 0 0 0; + padding-top: 5px; +} + +#supporter-form td { + padding-top: 10px; + vertical-align: top; +} + +#supporter-form .label { + text-align: right; + width: 205px; + padding-right: 10px; + padding-left: 10px; + font-size: 12px; + font-weight: bold; + white-space: nowrap; +} + +.input-item input, .input-item textarea { + /* thanks soundcloud! */ + background-image: url(http://static.ampify.it/gfx.button-repeat.png); + background-position: 0 -1200px; + background-repeat: repeat-x; + border: 1px solid #ccc; + border-radius: 5px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + color: #333; + font-size: 20px; + max-width: 220px; + padding: 3px 0 3px 3px; + width: 220px; +} + +.input-item select { + font-size: 16px; +} + +.male { + border: 2px solid #70b1e6; + background-color: #eaf3fb; +} + +.male .label { + color: #70b1e6; +} + +.female { + border: 2px solid #ed6aa4; + background-color: #fee5f5; +} + +.female .label { + color: #ed6aa4; +} + +#supporter-submit { + text-align: center; + padding: 0 0 15px 0; +} + +#support { + font-size: 20px; + margin-bottom: 15px; + margin-top: 5px; +} + +.male-counter { + color: #70b1e6; + font-size: 12px; + margin-bottom: -50px; + white-space: nowrap; +} + +.female-counter { + color: #ed6aa4; + font-size: 12px; + padding-left: 24px; + margin-bottom: -50px; + white-space: nowrap; +} + + +.tav-thanks { + font-size: 14px; + line-height: 26px; + margin: 12px 12px 12px 0; + color: #575757; + color: #000; + font-style: italic; +} + +.tav-thanks img { + float: right; + margin-left: 12px; +} + +.tav-thanks div { + text-align: right; + font-size: 12px; + line-height: 20px; + margin-top: 12px; +} +/* +.tav-thanks a { + color: #000; + text-decoration: underline; +} + +.tav-thanks a:hover { + text-decoration: none; +} +*/ + +.the-disqus-section { + margin: 12px 12px 12px 0; + min-height: 500px; +} + +.the-disqus-section h3 { + margin-top: 10px; + margin-bottom: 12px; + font-size: 20px; +} + +.action-items { + font-size: 14px; + line-height: 26px; + margin: 10px 24px; 20px 24px; +} + +.action-left { + float: left; + margin-right: 20px; +} + +.action-link { + margin-top: 20px; +} + +.action-text { + margin-top: 20px; +} + +/* plan file related css */ + +a.button { + background: transparent url('http://static.ampify.it/gfx.bg-button-a.gif') no-repeat scroll top right; + color: #444; + display: block; + float: left; + font: normal 12px arial, sans-serif; + height: 24px; + margin-right: 6px; + padding-right: 18px; /* sliding doors padding */ + text-decoration: none; +} + +a.button span { + background: transparent url('http://static.ampify.it/gfx.bg-button-span.gif') no-repeat; + display: block; + line-height: 14px; + padding: 5px 0 5px 18px; +} + +a.button:active { + background-position: bottom right; + color: #000; + outline: none; /* hide dotted outline in Firefox */ +} + +a.button:active span { + background-position: bottom left; + padding: 6px 0 4px 18px; /* push text down 1px */ +} + +a.buttondown { + background: transparent url('http://static.ampify.it/gfx.bg-button-a.gif') no-repeat scroll top right; + color: #444; + display: block; + float: left; + font: normal 12px arial, sans-serif; + height: 24px; + margin-right: 6px; + padding-right: 18px; /* sliding doors padding */ + text-decoration: none; + background-position: bottom right; + color: #000; + outline: none; /* hide dotted outline in Firefox */ +} + +a.buttondown span { + background: transparent url('http://static.ampify.it/gfx.bg-button-span.gif') no-repeat; + display: block; + line-height: 14px; + padding: 5px 0 5px 18px; + background-position: bottom left; + padding: 6px 0 4px 18px; /* push text down 1px */ +} + +.tag-segment { + text-align: right; +} + +.tag-segment span { + color: #fff; + padding: 0.5em; + font-size: 0.7em; +} + +.tag-link { + text-decoration: none; + color: #000; +} + +.tag { + background-color: #696969; +} + +.tag-val-done { + background-color: #007f16; + background-color: #00782d; + background-color: #006400; +} + +.tag-val-needsreview { + background-color: #a4ff00; + color: #000 !important; +} + +.tag-val-inreview { + background-color: #3056bf; +} + +.tag-val-todo { + background-color: #a60c00; + background-color: #d0006e; + background-color: #8B0000; +} + +.tag-val-wip { + background-color: #a66e00; + background-color: #ff550f; +} + +.tag-type-1 { +} + +.tag-type-2 { /* #hashtags */ + background-color: #2a4580; + background-color: #696969; +} + +.tag-type-dep { + display: none; +} + +.tag-type-milestone { + background-color: #00008B; + background-color: #06276f; + background-color: #a4ff00; /* nice colour! */ + /* color: #000 !important; */ + background-color: #002ca6; + background-color: #3056bf; + background-color: #898989; +} + +.tag-type-priority { + background-color: #481254; +} + +.tag-type-zuser { + background-color: #4573d5; + background-color: #696969; +} + +#plan-tags a, #site-tags a { + margin-bottom: 0.7em; +} + +#plan-container { + margin-top: 1.2em; + margin-bottom: 2.4em; +} + +.plan-help { + font-size: 0.9em; + font-weight: bold; + text-align: right; + margin-bottom: 1.4em; +} + +.container { + padding-left: 20px; +} + +.container blockquote { + padding: 0 0 0 30px; +} + +.container > p:first-child { + font-weight: bold; + font-family: "museo-1", "museo-2", Verdana; + padding-bottom: 0; +} + +.sidepic { + padding-top: 50px; + text-align: center; +} + +a#main_download { + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + border-radius: 5px; + margin-left: 10%; + margin-right: 10%; + padding: 5px; + display: block; + color: white; + background-color: #0b0; +} \ No newline at end of file Added: pypy/extradoc/pypy.org/download.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/download.html Tue Mar 9 18:25:52 2010 @@ -0,0 +1,221 @@ + + + + PyPy :: Download and install + + + + + + + + + + + + + + + +
+ +
+
+
+

Download and install

+

Here are the various binaries of PyPy 1.2 that we provide for x86 Linux, +Mac OS/X or Windows.

+ +

The release 1.2 of PyPy supports Python version 2.5. +If you are interested in helping +with 2.6, 2.7 or 3.x features, contact us!

+
+

“JIT Compiler” version

+

These binaries include a Just-in-Time compiler. They only work on +32-bit x86 (IA-32) CPUs that have the SSE2 instruction set (most of +them do, nowadays), as well as on any x86-64 machine in the 32-bit +compatibility mode.

+
    +
  • Linux binary
  • +
  • Mac OS/X binary
  • +
  • Windows binary (this version is alpha software!)
  • +
+

If your CPU is really old, it may not have SSE2. In this case, you need +to translate yourself with the option --jit-backend=x86-without-sse2.

+

If your CPU is a 64-bit machine and you want to translate a 32-bit +version of PyPy yourself, here are hints.

+

If you want to help us with implementing the 64-bit JIT backend, +contact us!

+
+
+

“No JIT” version

+

WARNING! Unless you really want to try this out, we recommend the JIT +version.

+

This version still has a few advantages over the JIT Compiler version. +Notably, for Python programs that require large amounts of memory (at +least a few hundred MBs), the following version of pypy-c runs them +by requiring generally 1.5x or 2x less memory than CPython. These +binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs +in the 32-bit compatibility mode.

+
    +
  • Linux binary
  • +
  • Mac OS/X binary
  • +
  • Windows binary
  • +
+

If your CPU is a 64-bit machine and you want to translate a 32-bit +version of PyPy yourself, here are hints.

+

If you want to help us with finishing the implementation of the native +64-bit version (there are a few known issues, like missing code in +ctypes to implement calls to C functions), contact us or +donate money!

+
+
+

“Sandbox” version

+

A special safe version. Read the docs about sandboxing. These +binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs +in the 32-bit compatibility mode.

+
    +
  • Linux binary
  • +
  • Mac OS/X binary
  • +
  • Windows binary
  • +
+

It is also possible to translate a version that includes both +sandboxing and the JIT compiler, although as the JIT is relatively +complicated, this reduce a bit the level of confidence we can put in it.

+

If your CPU is a 64-bit machine and you want to translate a 32-bit +version of PyPy yourself, here are hints.

+

The native 64-bit version needs testing and careful reviewing; +contact us!

+
+
+

“Stackless” version

+

Provides Stackless extensions, as well as greenlets. These +binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs +in the 32-bit compatibility mode.

+
    +
  • Linux binary
  • +
  • Mac OS/X binary
  • +
  • Windows binary
  • +
+

It is not possible right now to combine Stackless features with the JIT.

+

If your CPU is a 64-bit machine and you want to translate a 32-bit +version of PyPy yourself, here are hints.

+

For the native 64-bit version, see the issues of the no jit version..

+
+
+

Building from source

+
    +
  1. Get the source code. The following packages contain the source at +the same revision as the above binaries:

    + +

    Or you can checkout the current trunk using Subversion (the trunk +usually works and is of course more up-to-date):

    +
    +svn co http://codespeak.net/svn/pypy/trunk pypy-dist
    +
    +
  2. +
  3. Enter the goal directory:

    +
    +cd pypy-dist/pypy/translator/goal
    +
    +
  4. +
  5. Run the translate.py script. Here are the common combinations +of options:

    +
    +python translate.py -Ojit                # get the JIT version
    +python translate.py -O2                  # get the no-jit version
    +python translate.py --sandbox            # get the sandbox version
    +python translate.py --stackless          # get the stackless version
    +python translate.py -Ojit --backend=cli  # only for branch/cli-jit
    +
    +
  6. +
  7. Enjoy Mandelbrot :-) It takes on the order of one hour to +finish the translation, and 1.3 GB of RAM on a 32-bit system. +(Do not start a translation on a machine with 1GB or less!)

    +
  8. +
+
+

Note on building a 32-bit version on 64-bit systems

+

To build 32-bit versions of pypy-c you need to run translate.py +in a 32-bit version of Python. You can check with:

+
+$ python
+Python 2.6.2 (...)
+>>> import sys
+>>> sys.maxint
+
+

This prints 9223372036854775807 in 64-bit versions and 2147483647 in +32-bit versions.

+

On Linux, you may have to compile yourself a 32-bit Python, e.g.:

+
+cd Python-2.6.4
+CC="gcc -m32" LDFLAGS="-L/lib32 -L/usr/lib32 \
+  -L`pwd`/lib32 -Wl,-rpath,/lib32 -Wl,-rpath,/usr/lib32" \
+  ./configure
+make
+# and then use this ./python to run translate.py
+
+

On Mac OS/X: the easiest is to systematically use Python 2.5 when +working with PyPy. Indeed, the standard Python 2.5 runs in 32-bit mode.

+

On Windows, I only know about the solution of installing a 32-bit Python +manually.

+
+
+
+ +
+
+
+ + \ No newline at end of file Added: pypy/extradoc/pypy.org/image/header-background.png ============================================================================== Binary file. No diff available. Added: pypy/extradoc/pypy.org/image/pypy-logo.png ============================================================================== Binary file. No diff available. Modified: pypy/extradoc/pypy.org/index.html ============================================================================== --- pypy/extradoc/pypy.org/index.html (original) +++ pypy/extradoc/pypy.org/index.html Tue Mar 9 18:25:52 2010 @@ -1,16 +1,93 @@ - + - - - - - - -

- you should be redirected to - - http://codespeak.net/pypy/dist/pypy/ -

- - + + PyPy :: PyPy + + + + + + + + + + + + + + + +
+ +
+
+
+

PyPy

+

PyPy is a very compliant implementation of the Python language. +PyPy has several advantages and distinctive features:

+
+
    +
  • Speed: thanks to its Just-in-Time compiler, Python programs +often run faster on PyPy. (What is a JIT compiler?)
  • +
  • Memory usage: large, memory-hungry Python programs might end up +taking less space than they do in CPython.
  • +
  • Sandboxing: PyPy provides the ability to run untrusted code in a +fully secure way.
  • +
  • Stackless: PyPy can be configured to run in stackless mode, +providing micro-threads for massive concurrency.
  • +
  • As well as other features.
  • +
+
+

Download and try out the PyPy release 1.2!

+

To read more about Python, look into Python docs and check our +Compatibility page. PyPy can run such python libraries as twisted +and django and supports ctypes.

+
+ +
+
+
+ + \ No newline at end of file Added: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/js/detect.js Tue Mar 9 18:25:52 2010 @@ -0,0 +1,18 @@ + +$(document).ready(function() { + var download_url, download_text; + if (navigator.platform.indexOf('Linux') != -1) { + download_url = 'download/pypy-1.2.tar.bz2'; + download_text = 'Download linux i386 bin'; + } else if (navigator.platform.indexOf('Windows') != -1) { + download_url = 'download/pypy-1.2-win32.zip'; + download_text = 'Download Windows i386 bin'; + } else if (navigator.platform.indexOf('Mac') != 1) { + download_url = 'download/pypy-1.2-mac.tar.bz2'; + downloat_text = 'Download Mac OS X 10.6 bin'; + } else { + return; + } + $("#main_download").attr('href', download_url); + $("#main_download").text(download_text); +}); Added: pypy/extradoc/pypy.org/more.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/more.html Tue Mar 9 18:25:52 2010 @@ -0,0 +1,90 @@ + + + + PyPy :: More features + + + + + + + + + + + + + + + +
+ +
+
+
+

More features

+

PyPy has many secondary features and semi-independent +projects. We will mention here:

+
    +
  • the .NET backend: you get a version of pypy-c that runs +natively in the .NET/CLI VM. Of particular interest is the cli-jit +branch, in which you can make a version of pypy-c which also +contains a high-level JIT compiler (it compiles your Python programs +Just in Time into CLR bytecodes, which are in turn compiled natively +by the VM).
  • +
  • the Java backend: PyPy can run on the Java VM, but more +care is needed to finish this project. Writing a backend for our +high-level JIT compiler would be excellent. Contact us!
  • +
  • Other languages: available in a separate part of the repository, +we implemented other languages too: Prolog (almost complete), as +well as Smalltalk, JavaScript, Io, Scheme and Gameboy.
  • +
+
+ +
+
+
+ + \ No newline at end of file Added: pypy/extradoc/pypy.org/sandbox.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/sandbox.html Tue Mar 9 18:25:52 2010 @@ -0,0 +1,84 @@ + + + + PyPy :: Sandboxing + + + + + + + + + + + + + + + +
+ +
+
+
+

Sandboxing

+

PyPy's sandboxing is a working prototype for the idea of running untrusted +user programs. Unlike other sandboxing approaches for Python, PyPy's does not +try to limit language features considered “unsafe”. Instead we replace all +calls to external libraries (C or platform) with a stub that communicates +with an external process handling the policy.

+

To run the sandboxed process, get a sandboxed pypy-c and run:

+
+pypy_interact.py pypy-c-sandbox
+
+

To read more about its features, go to our dev site.

+
+ +
+
+
+ + \ No newline at end of file From fijal at codespeak.net Tue Mar 9 18:31:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:31:23 +0100 (CET) Subject: [pypy-svn] r71980 - pypy/extradoc/pypy.org/js Message-ID: <20100309173123.61ACC282B9D@codespeak.net> Author: fijal Date: Tue Mar 9 18:31:22 2010 New Revision: 71980 Modified: pypy/extradoc/pypy.org/js/detect.js Log: Add a failsafe here that goes to download page Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Tue Mar 9 18:31:22 2010 @@ -11,7 +11,8 @@ download_url = 'download/pypy-1.2-mac.tar.bz2'; downloat_text = 'Download Mac OS X 10.6 bin'; } else { - return; + download_url = "download.html"; + download_text = "Download page"; } $("#main_download").attr('href', download_url); $("#main_download").text(download_text); From fijal at codespeak.net Tue Mar 9 18:33:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:33:48 +0100 (CET) Subject: [pypy-svn] r71981 - pypy/extradoc/pypy.org/js Message-ID: <20100309173348.5ED57282B90@codespeak.net> Author: fijal Date: Tue Mar 9 18:33:47 2010 New Revision: 71981 Modified: pypy/extradoc/pypy.org/js/detect.js Log: change windows to win Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Tue Mar 9 18:33:47 2010 @@ -4,7 +4,7 @@ if (navigator.platform.indexOf('Linux') != -1) { download_url = 'download/pypy-1.2.tar.bz2'; download_text = 'Download linux i386 bin'; - } else if (navigator.platform.indexOf('Windows') != -1) { + } else if (navigator.platform.indexOf('Win') != -1) { download_url = 'download/pypy-1.2-win32.zip'; download_text = 'Download Windows i386 bin'; } else if (navigator.platform.indexOf('Mac') != 1) { From fijal at codespeak.net Tue Mar 9 18:35:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:35:42 +0100 (CET) Subject: [pypy-svn] r71982 - pypy/extradoc/pypy.org/source user/fijal/website Message-ID: <20100309173542.C0CB5282B90@codespeak.net> Author: fijal Date: Tue Mar 9 18:35:41 2010 New Revision: 71982 Added: pypy/extradoc/pypy.org/source/ - copied from r71981, user/fijal/website/ Removed: user/fijal/website/ Log: Move the website to somehow more official place From fijal at codespeak.net Tue Mar 9 18:37:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:37:15 +0100 (CET) Subject: [pypy-svn] r71983 - pypy/extradoc/pypy.org/source Message-ID: <20100309173715.EB244282B90@codespeak.net> Author: fijal Date: Tue Mar 9 18:37:14 2010 New Revision: 71983 Modified: pypy/extradoc/pypy.org/source/README Log: update readme Modified: pypy/extradoc/pypy.org/source/README ============================================================================== --- pypy/extradoc/pypy.org/source/README (original) +++ pypy/extradoc/pypy.org/source/README Tue Mar 9 18:37:14 2010 @@ -4,10 +4,10 @@ by running -yatiblog you'll get a website subdirectory which -contains all necessary stuff to upload and deploy. +yatiblog -o you'll get output in +output directory that contains all necessary stuff to upload and deploy. -Other required dependencies (argh): - * "genshi" from http://genshi.edgewall.org/ +Other required dependencies: + * "genshi" from "easy_install genshi" * "pygments" from "easy_install pygments" - * "yaml" from ... (I give up at that point, as this doesn't compile) + * "yaml" from "apt-get install libyaml", "easy_install pyyaml" From fijal at codespeak.net Tue Mar 9 18:40:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:40:20 +0100 (CET) Subject: [pypy-svn] r71984 - pypy/extradoc/pypy.org/source Message-ID: <20100309174020.8A864282B90@codespeak.net> Author: fijal Date: Tue Mar 9 18:40:19 2010 New Revision: 71984 Modified: pypy/extradoc/pypy.org/source/README Log: fix package name Modified: pypy/extradoc/pypy.org/source/README ============================================================================== --- pypy/extradoc/pypy.org/source/README (original) +++ pypy/extradoc/pypy.org/source/README Tue Mar 9 18:40:19 2010 @@ -10,4 +10,4 @@ Other required dependencies: * "genshi" from "easy_install genshi" * "pygments" from "easy_install pygments" - * "yaml" from "apt-get install libyaml", "easy_install pyyaml" + * "yaml" from "apt-get install libyaml-dev", "easy_install pyyaml" From fijal at codespeak.net Tue Mar 9 18:46:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 9 Mar 2010 18:46:17 +0100 (CET) Subject: [pypy-svn] r71985 - in pypy/extradoc/pypy.org: . source Message-ID: <20100309174617.8FCA1282B90@codespeak.net> Author: fijal Date: Tue Mar 9 18:46:15 2010 New Revision: 71985 Modified: pypy/extradoc/pypy.org/archive.html pypy/extradoc/pypy.org/compat.html pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/index.html pypy/extradoc/pypy.org/more.html pypy/extradoc/pypy.org/sandbox.html pypy/extradoc/pypy.org/source/_config.yml Log: Update google analytics UA Modified: pypy/extradoc/pypy.org/archive.html ============================================================================== --- pypy/extradoc/pypy.org/archive.html (original) +++ pypy/extradoc/pypy.org/archive.html Tue Mar 9 18:46:15 2010 @@ -17,7 +17,7 @@ + + + + + + +
+ +
+
+
+

Features

+

PyPy 1.2 implements Python 2.5. It supports all of the core +language, passing Python test suite (with minor modifications that were +already accepted in main python in newer versions). It supports most +of commonly used Python standard library modules. For known differences +with CPython, see our compatibility page. If you are interested in +helping with 2.6, 2.7 or 3.x features, contact us!

+

PyPy 1.2 runs essentially only on Intel x86 (IA-32). On 64-bit platforms +you have to use the 32-bit compatibility mode, for now — or contact us +to help!

+
+

Speed or memory usage?

+

Our main prototype comes with a Just-in-Time compiler. It is +really fast in running most benchmarks. Try it out!

+

An issue with our JIT compiler is that it's hard to control +the exact amount of RAM that is used. If this is an important +issue to you, you can try our baseline version, which does +not include a JIT compiler at all.

+
+
+

Sandboxing

+

PyPy's sandboxing is a working prototype for the idea of running untrusted +user programs. Unlike other sandboxing approaches for Python, PyPy's does not +try to limit language features considered “unsafe”. Instead we replace all +calls to external libraries (C or platform) with a stub that communicates +with an external process handling the policy.

+

To run the sandboxed process, get a sandboxed pypy-c and run:

+
+pypy_interact.py pypy-c-sandbox
+
+

To read more about its features, go to our dev site.

+
+
+

Stackless

+

PyPy is also available in a separate Stackless version that includes +support for micro-threads for massive concurrency. Read more about +it at the Stackless main site (we provide the same interface as the +standard Stackless Python), and at the greenlets page.

+
+
+

Other features

+

PyPy has many secondary features and semi-independent +projects. We will mention here:

+
    +
  • the .NET backend: you get a version of pypy-c that runs +natively in the .NET/CLI VM. Of particular interest is the cli-jit +branch, in which you can make a version of pypy-c which also +contains a high-level JIT compiler (it compiles your Python programs +Just in Time into CLR bytecodes, which are in turn compiled natively +by the VM).
  • +
  • the Java backend: PyPy can run on the Java VM, but more care is +needed to finish this project. (Requires the cli-jit branch for +now.) Writing a backend for our high-level JIT compiler would be +excellent. Contact us!
  • +
  • Other languages: available in a separate part of the repository, +we implemented other languages too: Prolog (almost complete), as +well as Smalltalk, JavaScript, Io, Scheme and Gameboy.
  • +
+
+
+ +
+
+
+ + \ No newline at end of file Modified: pypy/extradoc/pypy.org/index.html ============================================================================== --- pypy/extradoc/pypy.org/index.html (original) +++ pypy/extradoc/pypy.org/index.html Wed Mar 10 15:52:04 2010 @@ -40,7 +40,7 @@ -->
- +
@@ -55,11 +55,11 @@ often run faster on PyPy. (What is a JIT compiler?)
  • Memory usage: large, memory-hungry Python programs might end up taking less space than they do in CPython.
  • -
  • Sandboxing: PyPy provides the ability to run untrusted code in a +
  • Sandboxing: PyPy provides the ability to run untrusted code in a fully secure way.
  • Stackless: PyPy can be configured to run in stackless mode, providing micro-threads for massive concurrency.
  • -
  • As well as other features.
  • +
  • As well as other features.
  • Download and try out the PyPy release 1.2!

    From arigo at codespeak.net Wed Mar 10 15:52:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 15:52:17 +0100 (CET) Subject: [pypy-svn] r72056 - pypy/release/1.2.x/pypy/doc Message-ID: <20100310145217.4CF81282B90@codespeak.net> Author: arigo Date: Wed Mar 10 15:52:15 2010 New Revision: 72056 Modified: pypy/release/1.2.x/pypy/doc/windows.txt Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r72053:72054 Modified: pypy/release/1.2.x/pypy/doc/windows.txt ============================================================================== --- pypy/release/1.2.x/pypy/doc/windows.txt (original) +++ pypy/release/1.2.x/pypy/doc/windows.txt Wed Mar 10 15:52:15 2010 @@ -91,7 +91,7 @@ perl Configure VC-WIN32 ms\do_ms.bat - nmake -f ms\ntdll.mak install + nmake -f ms\nt.mak install Using the mingw compiler ------------------------ From fijal at codespeak.net Wed Mar 10 15:54:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 15:54:34 +0100 (CET) Subject: [pypy-svn] r72057 - pypy/extradoc/pypy.org Message-ID: <20100310145434.60926282B90@codespeak.net> Author: fijal Date: Wed Mar 10 15:54:32 2010 New Revision: 72057 Modified: pypy/extradoc/pypy.org/compat.html pypy/extradoc/pypy.org/download.html Log: oops, sorry, checkin everything Modified: pypy/extradoc/pypy.org/compat.html ============================================================================== --- pypy/extradoc/pypy.org/compat.html (original) +++ pypy/extradoc/pypy.org/compat.html Wed Mar 10 15:54:32 2010 @@ -40,7 +40,7 @@
    -->
    - +
    @@ -81,6 +81,12 @@

    The proper fix is:

    +f = open("filename", "w")
    +f.write("stuff")
    +f.close()
    +
    +

    or using the with keyword:

    +
     with open("filename", "w") as f:
         f.write("stuff")
     
    @@ -101,6 +107,7 @@

    won't work.

    +

    A more complete list is available at our dev site.

    -->
    - +
    @@ -49,17 +49,26 @@

    Download and install

    Here are the various binaries of PyPy 1.2 that we provide for x86 Linux, Mac OS/X or Windows.

    -

    Warning: site in progress, no binaries available yet

    -
      + +++ + + + + +
      -

      The release 1.2 of PyPy supports Python version 2.5. -If you are interested in helping -with 2.6, 2.7 or 3.x features, contact us!

      +

      “JIT Compiler” version

      These binaries include a Just-in-Time compiler. They only work on @@ -102,7 +111,7 @@

      “Sandbox” version

      -

      A special safe version. Read the docs about sandboxing. These +

      A special safe version. Read the docs about sandboxing. These binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs in the 32-bit compatibility mode.

      +
      +

      Installing

      +

      All versions are packaged in a tar.bz2 or zip file. When +uncompressed, they run in-place. On Linux or Mac OS/X, they can also be +installed by manually moving the files in the following directories:

      +
      +/usr/bin/pypy-c
      +/usr/share/pypy-1.2/lib-python/*
      +/usr/share/pypy-1.2/pypy/*
      +
      +

      You can also install it to /usr/local/bin and /usr/local/share.

      +

      Building from source

      1. Get the source code. The following packages contain the source at the same revision as the above binaries:

        Or you can checkout the current trunk using Subversion (the trunk usually works and is of course more up-to-date):

         svn co http://codespeak.net/svn/pypy/trunk pypy-dist
         
        +

        Windows users trying the tarballs are expected to use MSVC. +The trunk version contains fixes to support MinGW32. More +information on our dev site.

      2. Enter the goal directory:

        @@ -219,4 +243,4 @@
         
    - + \ No newline at end of file From fijal at codespeak.net Wed Mar 10 15:54:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 15:54:49 +0100 (CET) Subject: [pypy-svn] r72058 - pypy/extradoc/pypy.org Message-ID: <20100310145449.986BB282B90@codespeak.net> Author: fijal Date: Wed Mar 10 15:54:48 2010 New Revision: 72058 Removed: pypy/extradoc/pypy.org/more.html pypy/extradoc/pypy.org/sandbox.html Log: These pages are gone From fijal at codespeak.net Wed Mar 10 15:56:46 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 15:56:46 +0100 (CET) Subject: [pypy-svn] r72059 - in pypy/extradoc/pypy.org: . source Message-ID: <20100310145646.AB990282B90@codespeak.net> Author: fijal Date: Wed Mar 10 15:56:45 2010 New Revision: 72059 Modified: pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/source/download.txt Log: kill donate money there Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Wed Mar 10 15:56:45 2010 @@ -106,8 +106,7 @@ version of PyPy yourself, here are hints.

    If you want to help us with finishing the implementation of the native 64-bit version (there are a few known issues, like missing code in -ctypes to implement calls to C functions), contact us or -donate money!

    +ctypes to implement calls to C functions), contact us.

    “Sandbox” version

    Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Wed Mar 10 15:56:45 2010 @@ -71,8 +71,7 @@ If you want to help us with finishing the implementation of the native 64-bit version (there are a few known issues, like missing code in -`ctypes`_ to implement calls to C functions), `contact us`_ or -**donate money**! +`ctypes`_ to implement calls to C functions), `contact us`_. .. _`Sandboxed version`: From arigo at codespeak.net Wed Mar 10 16:06:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 16:06:53 +0100 (CET) Subject: [pypy-svn] r72060 - pypy/extradoc/pypy.org/source Message-ID: <20100310150653.7EF8E282B90@codespeak.net> Author: arigo Date: Wed Mar 10 16:06:52 2010 New Revision: 72060 Modified: pypy/extradoc/pypy.org/source/TODO Log: Write in TODO. Modified: pypy/extradoc/pypy.org/source/TODO ============================================================================== --- pypy/extradoc/pypy.org/source/TODO (original) +++ pypy/extradoc/pypy.org/source/TODO Wed Mar 10 16:06:52 2010 @@ -1,7 +1,5 @@ -* drop-down or other menu that allows a one-click access to each - of the pages here. Also do you feel like explaining why you insist - on adding "or donate money" after exactly one of the "contact us" in - download.txt? +* kill "alpha software" after Windows. Add "it's all beta software" + somewhere. * svn cp release/1.2.x release/1.2.0 * svn cp release/1.2.x dist From arigo at codespeak.net Wed Mar 10 16:17:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 16:17:34 +0100 (CET) Subject: [pypy-svn] r72061 - pypy/trunk/pypy/lib Message-ID: <20100310151734.EEBF7282B9E@codespeak.net> Author: arigo Date: Wed Mar 10 16:17:31 2010 New Revision: 72061 Modified: pypy/trunk/pypy/lib/_locale.py Log: Fix _locale to handle the case where we don't have the 'gettext' family of functions. Modified: pypy/trunk/pypy/lib/_locale.py ============================================================================== --- pypy/trunk/pypy/lib/_locale.py (original) +++ pypy/trunk/pypy/lib/_locale.py Wed Mar 10 16:17:31 2010 @@ -97,32 +97,33 @@ _strxfrm.argtypes = (c_char_p, c_char_p, size_t) _strxfrm.restype = size_t -_gettext = libc.gettext -_gettext.argtypes = (c_char_p,) -_gettext.restype = c_char_p - -_dgettext = libc.dgettext -_dgettext.argtypes = (c_char_p, c_char_p) -_dgettext.restype = c_char_p - -_dcgettext = libc.dcgettext -_dcgettext.argtypes = (c_char_p, c_char_p, c_int) -_dcgettext.restype = c_char_p - -_textdomain = libc.textdomain -_textdomain.argtypes = (c_char_p,) -_textdomain.restype = c_char_p - -_bindtextdomain = libc.bindtextdomain -_bindtextdomain.argtypes = (c_char_p, c_char_p) -_bindtextdomain.restype = c_char_p - -try: - _bind_textdomain_codeset = libc.bindtextdomain_codeset - _bind_textdomain_codeset.argtypes = (c_char_p, c_char_p) - _bind_textdomain_codeset.restype = c_char_p -except AttributeError: - _bind_textdomain_codeset = None +HAS_LIBINTL = hasattr(libc, 'gettext') +if HAS_LIBINTL: + _gettext = libc.gettext + _gettext.argtypes = (c_char_p,) + _gettext.restype = c_char_p + + _dgettext = libc.dgettext + _dgettext.argtypes = (c_char_p, c_char_p) + _dgettext.restype = c_char_p + + _dcgettext = libc.dcgettext + _dcgettext.argtypes = (c_char_p, c_char_p, c_int) + _dcgettext.restype = c_char_p + + _textdomain = libc.textdomain + _textdomain.argtypes = (c_char_p,) + _textdomain.restype = c_char_p + + _bindtextdomain = libc.bindtextdomain + _bindtextdomain.argtypes = (c_char_p, c_char_p) + _bindtextdomain.restype = c_char_p + + HAS_BIND_TEXTDOMAIN_CODESET = hasattr(libc, 'bindtextdomain_codeset') + if HAS_BIND_TEXTDOMAIN_CODESET: + _bind_textdomain_codeset = libc.bindtextdomain_codeset + _bind_textdomain_codeset.argtypes = (c_char_p, c_char_p) + _bind_textdomain_codeset.restype = c_char_p class Error(Exception): pass @@ -268,51 +269,53 @@ return result raise ValueError("unsupported langinfo constant") -def gettext(msg): - """gettext(msg) -> string - Return translation of msg.""" - return _gettext(msg) - -def dgettext(domain, msg): - """dgettext(domain, msg) -> string - Return translation of msg in domain.""" - return _dgettext(domain, msg) - -def dcgettext(domain, msg, category): - """dcgettext(domain, msg, category) -> string - Return translation of msg in domain and category.""" - return _dcgettext(domain, msg, category) - -def textdomain(domain): - """textdomain(domain) -> string - Set the C library's textdomain to domain, returning the new domain.""" - return _textdomain(domain) - -def bindtextdomain(domain, dir): - """bindtextdomain(domain, dir) -> string - Bind the C library's domain to dir.""" - dirname = _bindtextdomain(domain, dir) - if not dirname: - errno = get_errno() - raise OSError(errno) - return dirname - -if _bind_textdomain_codeset: - def bind_textdomain_codeset(domain, codeset): - """bind_textdomain_codeset(domain, codeset) -> string - Bind the C library's domain to codeset.""" - codeset = _bind_textdomain_codeset(domain, codeset) - if codeset: - return codeset - return None +if HAS_LIBINTL: + def gettext(msg): + """gettext(msg) -> string + Return translation of msg.""" + return _gettext(msg) + + def dgettext(domain, msg): + """dgettext(domain, msg) -> string + Return translation of msg in domain.""" + return _dgettext(domain, msg) + + def dcgettext(domain, msg, category): + """dcgettext(domain, msg, category) -> string + Return translation of msg in domain and category.""" + return _dcgettext(domain, msg, category) + + def textdomain(domain): + """textdomain(domain) -> string + Set the C library's textdomain to domain, returning the new domain.""" + return _textdomain(domain) + + def bindtextdomain(domain, dir): + """bindtextdomain(domain, dir) -> string + Bind the C library's domain to dir.""" + dirname = _bindtextdomain(domain, dir) + if not dirname: + errno = get_errno() + raise OSError(errno) + return dirname + + if HAS_BIND_TEXTDOMAIN_CODESET: + def bind_textdomain_codeset(domain, codeset): + """bind_textdomain_codeset(domain, codeset) -> string + Bind the C library's domain to codeset.""" + codeset = _bind_textdomain_codeset(domain, codeset) + if codeset: + return codeset + return None __all__ = ( 'Error', 'setlocale', 'localeconv', 'strxfrm', 'strcoll', - 'gettext', 'dgettext', 'dcgettext', 'textdomain', - 'bindtextdomain', ) + ALL_CONSTANTS -if _bind_textdomain_codeset: - __all__ += ('bind_textdomain_codeset',) +if HAS_LIBINTL: + __all__ += ('gettext', 'dgettext', 'dcgettext', 'textdomain', + 'bindtextdomain') + if HAS_BIND_TEXTDOMAIN_CODESET: + __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: __all__ += ('nl_langinfo',) From arigo at codespeak.net Wed Mar 10 16:20:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 16:20:02 +0100 (CET) Subject: [pypy-svn] r72062 - pypy/release/1.2.x/pypy/lib Message-ID: <20100310152002.23E23282B9E@codespeak.net> Author: arigo Date: Wed Mar 10 16:20:00 2010 New Revision: 72062 Modified: pypy/release/1.2.x/pypy/lib/_locale.py Log: svn merge svn+ssh://codespeak.net/svn/pypy/trunk -r72060:72061 Modified: pypy/release/1.2.x/pypy/lib/_locale.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/_locale.py (original) +++ pypy/release/1.2.x/pypy/lib/_locale.py Wed Mar 10 16:20:00 2010 @@ -97,32 +97,33 @@ _strxfrm.argtypes = (c_char_p, c_char_p, size_t) _strxfrm.restype = size_t -_gettext = libc.gettext -_gettext.argtypes = (c_char_p,) -_gettext.restype = c_char_p - -_dgettext = libc.dgettext -_dgettext.argtypes = (c_char_p, c_char_p) -_dgettext.restype = c_char_p - -_dcgettext = libc.dcgettext -_dcgettext.argtypes = (c_char_p, c_char_p, c_int) -_dcgettext.restype = c_char_p - -_textdomain = libc.textdomain -_textdomain.argtypes = (c_char_p,) -_textdomain.restype = c_char_p - -_bindtextdomain = libc.bindtextdomain -_bindtextdomain.argtypes = (c_char_p, c_char_p) -_bindtextdomain.restype = c_char_p - -try: - _bind_textdomain_codeset = libc.bindtextdomain_codeset - _bind_textdomain_codeset.argtypes = (c_char_p, c_char_p) - _bind_textdomain_codeset.restype = c_char_p -except AttributeError: - _bind_textdomain_codeset = None +HAS_LIBINTL = hasattr(libc, 'gettext') +if HAS_LIBINTL: + _gettext = libc.gettext + _gettext.argtypes = (c_char_p,) + _gettext.restype = c_char_p + + _dgettext = libc.dgettext + _dgettext.argtypes = (c_char_p, c_char_p) + _dgettext.restype = c_char_p + + _dcgettext = libc.dcgettext + _dcgettext.argtypes = (c_char_p, c_char_p, c_int) + _dcgettext.restype = c_char_p + + _textdomain = libc.textdomain + _textdomain.argtypes = (c_char_p,) + _textdomain.restype = c_char_p + + _bindtextdomain = libc.bindtextdomain + _bindtextdomain.argtypes = (c_char_p, c_char_p) + _bindtextdomain.restype = c_char_p + + HAS_BIND_TEXTDOMAIN_CODESET = hasattr(libc, 'bindtextdomain_codeset') + if HAS_BIND_TEXTDOMAIN_CODESET: + _bind_textdomain_codeset = libc.bindtextdomain_codeset + _bind_textdomain_codeset.argtypes = (c_char_p, c_char_p) + _bind_textdomain_codeset.restype = c_char_p class Error(Exception): pass @@ -268,51 +269,53 @@ return result raise ValueError("unsupported langinfo constant") -def gettext(msg): - """gettext(msg) -> string - Return translation of msg.""" - return _gettext(msg) - -def dgettext(domain, msg): - """dgettext(domain, msg) -> string - Return translation of msg in domain.""" - return _dgettext(domain, msg) - -def dcgettext(domain, msg, category): - """dcgettext(domain, msg, category) -> string - Return translation of msg in domain and category.""" - return _dcgettext(domain, msg, category) - -def textdomain(domain): - """textdomain(domain) -> string - Set the C library's textdomain to domain, returning the new domain.""" - return _textdomain(domain) - -def bindtextdomain(domain, dir): - """bindtextdomain(domain, dir) -> string - Bind the C library's domain to dir.""" - dirname = _bindtextdomain(domain, dir) - if not dirname: - errno = get_errno() - raise OSError(errno) - return dirname - -if _bind_textdomain_codeset: - def bind_textdomain_codeset(domain, codeset): - """bind_textdomain_codeset(domain, codeset) -> string - Bind the C library's domain to codeset.""" - codeset = _bind_textdomain_codeset(domain, codeset) - if codeset: - return codeset - return None +if HAS_LIBINTL: + def gettext(msg): + """gettext(msg) -> string + Return translation of msg.""" + return _gettext(msg) + + def dgettext(domain, msg): + """dgettext(domain, msg) -> string + Return translation of msg in domain.""" + return _dgettext(domain, msg) + + def dcgettext(domain, msg, category): + """dcgettext(domain, msg, category) -> string + Return translation of msg in domain and category.""" + return _dcgettext(domain, msg, category) + + def textdomain(domain): + """textdomain(domain) -> string + Set the C library's textdomain to domain, returning the new domain.""" + return _textdomain(domain) + + def bindtextdomain(domain, dir): + """bindtextdomain(domain, dir) -> string + Bind the C library's domain to dir.""" + dirname = _bindtextdomain(domain, dir) + if not dirname: + errno = get_errno() + raise OSError(errno) + return dirname + + if HAS_BIND_TEXTDOMAIN_CODESET: + def bind_textdomain_codeset(domain, codeset): + """bind_textdomain_codeset(domain, codeset) -> string + Bind the C library's domain to codeset.""" + codeset = _bind_textdomain_codeset(domain, codeset) + if codeset: + return codeset + return None __all__ = ( 'Error', 'setlocale', 'localeconv', 'strxfrm', 'strcoll', - 'gettext', 'dgettext', 'dcgettext', 'textdomain', - 'bindtextdomain', ) + ALL_CONSTANTS -if _bind_textdomain_codeset: - __all__ += ('bind_textdomain_codeset',) +if HAS_LIBINTL: + __all__ += ('gettext', 'dgettext', 'dcgettext', 'textdomain', + 'bindtextdomain') + if HAS_BIND_TEXTDOMAIN_CODESET: + __all__ += ('bind_textdomain_codeset',) if HAS_LANGINFO: __all__ += ('nl_langinfo',) From afa at codespeak.net Wed Mar 10 16:24:08 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 10 Mar 2010 16:24:08 +0100 (CET) Subject: [pypy-svn] r72063 - pypy/trunk/pypy/tool Message-ID: <20100310152408.C61BC282B9E@codespeak.net> Author: afa Date: Wed Mar 10 16:24:07 2010 New Revision: 72063 Modified: pypy/trunk/pypy/tool/win32-build.bat Log: minor change Modified: pypy/trunk/pypy/tool/win32-build.bat ============================================================================== --- pypy/trunk/pypy/tool/win32-build.bat (original) +++ pypy/trunk/pypy/tool/win32-build.bat Wed Mar 10 16:24:07 2010 @@ -9,17 +9,17 @@ set TARGET=pypy/translator/goal/targetpypystandalone set TARGETOPTS= -set ZIPFILE=pypy-1.2-win32.zip - %PYTHON% %TRANSLATE% --output=pypy-c.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% %PYTHON% %TRANSLATE% -Ojit --output=pypy-jit.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% %PYTHON% %TRANSLATE% --stackless --output=pypy-stackless.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% %PYTHON% %TRANSLATE% --sandbox --output=pypy-sandbox.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% +set ZIP=zip.exe +set ZIPFILE=pypy-1.2-win32.zip copy ..\expat-2.0.1\win32\bin\release\libexpat.dll . del /s pypy\lib\*.pyc lib-python\*.pyc del %ZIPFILE% -zip %ZIPFILE% *.exe *.dll -zip -r %ZIPFILE% pypy\lib lib-python -zip -d %ZIPFILE% lib-python\2.5.2\plat-* +%ZIP% %ZIPFILE% *.exe *.dll +%ZIP% -r %ZIPFILE% pypy\lib lib-python +%ZIP% -d %ZIPFILE% lib-python\2.5.2\plat-* From fijal at codespeak.net Wed Mar 10 16:25:13 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 16:25:13 +0100 (CET) Subject: [pypy-svn] r72064 - in pypy/extradoc/pypy.org: . source Message-ID: <20100310152513.40930282B9E@codespeak.net> Author: fijal Date: Wed Mar 10 16:25:12 2010 New Revision: 72064 Modified: pypy/extradoc/pypy.org/compat.html pypy/extradoc/pypy.org/source/compat.txt Log: use syntax highlightning Modified: pypy/extradoc/pypy.org/compat.html ============================================================================== --- pypy/extradoc/pypy.org/compat.html (original) +++ pypy/extradoc/pypy.org/compat.html Wed Mar 10 16:25:12 2010 @@ -75,21 +75,12 @@
    • PyPy does not support refcounting semantics. The code below won't fill the file immediately, but only after a certain period -of time, when the GC will collect:

      -
      -open("filename", "w").write("stuff")
      -
      -

      The proper fix is:

      -
      -f = open("filename", "w")
      -f.write("stuff")
      -f.close()
      -
      -

      or using the with keyword:

      -
      -with open("filename", "w") as f:
      -    f.write("stuff")
      -
      +of time, when the GC will collect

      +
      open("filename", "w").write("stuff")
      +

      The proper fix is

      +
      f = open("filename", "w")
      f.write("stuff")
      f.close()
      +

      or using the with keyword

      +
      with open("filename", "w") as f:
      f.write("stuff")
    • We don't support certain attributes that were decided to be implementation-dependent. For example, gc.get_referrers does not exist. @@ -99,11 +90,8 @@

    • You can't attach a __del__ method to a class after its creation.

    • -
    • You can't store non-string keys in type objects. Example:

      -
      -class A(object):
      -    locals()[42] = 3
      -
      +
    • You can't store non-string keys in type objects. Example

      +
      class A(object):
      locals()[42] = 3

      won't work.

    Modified: pypy/extradoc/pypy.org/source/compat.txt ============================================================================== --- pypy/extradoc/pypy.org/source/compat.txt (original) +++ pypy/extradoc/pypy.org/source/compat.txt Wed Mar 10 16:25:12 2010 @@ -39,17 +39,23 @@ * PyPy does not support refcounting semantics. The code below won't fill the file immediately, but only after a certain period - of time, when the GC will collect:: + of time, when the GC will collect + + .. syntax:: python open("filename", "w").write("stuff") - The proper fix is:: + The proper fix is + + .. syntax:: python f = open("filename", "w") f.write("stuff") f.close() - or using the ``with`` keyword:: + or using the ``with`` keyword + + .. syntax:: python with open("filename", "w") as f: f.write("stuff") @@ -62,7 +68,9 @@ * You can't attach a ``__del__`` method to a class after its creation. -* You can't store non-string keys in type objects. Example:: +* You can't store non-string keys in type objects. Example + + .. syntax:: python class A(object): locals()[42] = 3 From afa at codespeak.net Wed Mar 10 16:25:18 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 10 Mar 2010 16:25:18 +0100 (CET) Subject: [pypy-svn] r72065 - pypy/trunk/pypy/tool/test Message-ID: <20100310152518.AA32F282BDA@codespeak.net> Author: afa Date: Wed Mar 10 16:25:16 2010 New Revision: 72065 Modified: pypy/trunk/pypy/tool/test/test_package.py Log: Attempt to fix the test when pypy-c is not compiled (most buildbots run python2.5 where this module is skipped) Modified: pypy/trunk/pypy/tool/test/test_package.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_package.py (original) +++ pypy/trunk/pypy/tool/test/test_package.py Wed Mar 10 16:25:16 2010 @@ -2,13 +2,13 @@ import py from pypy.tool.autopath import pypydir from pypy.tool.package import main -import tarfile +import tarfile, os def test_dir_structure(): # make sure we have sort of pypy-c pypy_c = py.path.local(pypydir).join('translator', 'goal', 'pypy-c') if not pypy_c.check(): - shutil.copy("/usr/bin/echo", pypy_c) + os.system("echo faked_pypy_c> %s" % (pypy_c,)) fake_pypy_c = True else: fake_pypy_c = False From arigo at codespeak.net Wed Mar 10 16:27:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 16:27:52 +0100 (CET) Subject: [pypy-svn] r72066 - pypy/extradoc/pypy.org/source Message-ID: <20100310152752.A659B282B9E@codespeak.net> Author: arigo Date: Wed Mar 10 16:27:51 2010 New Revision: 72066 Modified: pypy/extradoc/pypy.org/source/download.txt Log: Fix the name. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Wed Mar 10 16:27:51 2010 @@ -147,7 +147,7 @@ Or you can checkout the current trunk using Subversion_ (the trunk usually works and is of course more up-to-date):: - svn co http://codespeak.net/svn/pypy/trunk pypy-dist + svn co http://codespeak.net/svn/pypy/trunk pypy-trunk Windows users trying the tarballs are expected to use MSVC. The trunk version contains fixes to support MinGW32. More From arigo at codespeak.net Wed Mar 10 16:27:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Mar 2010 16:27:58 +0100 (CET) Subject: [pypy-svn] r72067 - pypy/extradoc/pypy.org/source Message-ID: <20100310152758.4A767282B9E@codespeak.net> Author: arigo Date: Wed Mar 10 16:27:56 2010 New Revision: 72067 Modified: pypy/extradoc/pypy.org/source/TODO Log: Add a TODO. Modified: pypy/extradoc/pypy.org/source/TODO ============================================================================== --- pypy/extradoc/pypy.org/source/TODO (original) +++ pypy/extradoc/pypy.org/source/TODO Wed Mar 10 16:27:56 2010 @@ -1,5 +1,5 @@ * kill "alpha software" after Windows. Add "it's all beta software" - somewhere. + somewhere. Fix the box at the start of download.txt. * svn cp release/1.2.x release/1.2.0 * svn cp release/1.2.x dist From fijal at codespeak.net Wed Mar 10 16:50:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 16:50:48 +0100 (CET) Subject: [pypy-svn] r72068 - in pypy/extradoc/pypy.org: . css source Message-ID: <20100310155048.9D560282BAD@codespeak.net> Author: fijal Date: Wed Mar 10 16:50:47 2010 New Revision: 72068 Modified: pypy/extradoc/pypy.org/css/site.css pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/source/README pypy/extradoc/pypy.org/source/download.txt Log: Upload my fight with a box Modified: pypy/extradoc/pypy.org/css/site.css ============================================================================== --- pypy/extradoc/pypy.org/css/site.css (original) +++ pypy/extradoc/pypy.org/css/site.css Wed Mar 10 16:50:47 2010 @@ -1349,4 +1349,11 @@ display: block; color: white; background-color: #0b0; -} \ No newline at end of file +} + +fieldset#block_id { + background-color: #F0F0F0; + font-size: 10pt; + margin-left: 20px; + maring-right: 20px; +} Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Wed Mar 10 16:50:47 2010 @@ -49,12 +49,8 @@

    Download and install

    Here are the various binaries of PyPy 1.2 that we provide for x86 Linux, Mac OS/X or Windows.

    - --- - - - - -
    -
    +
    +

    “JIT Compiler” version

    These binaries include a Just-in-Time compiler. They only work on 32-bit x86 (IA-32) CPUs that have the SSE2 instruction set (most of Modified: pypy/extradoc/pypy.org/source/README ============================================================================== --- pypy/extradoc/pypy.org/source/README (original) +++ pypy/extradoc/pypy.org/source/README Wed Mar 10 16:50:47 2010 @@ -1,6 +1,6 @@ You generate this website by using yatiblog from here: -http://github.com/tav/ampify/blob/master/environ/startup/yatiblog +http://github.com/fijal/ampify/blob/master/environ/startup/yatiblog by running Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Wed Mar 10 16:50:47 2010 @@ -9,18 +9,17 @@ Here are the various binaries of **PyPy 1.2** that we provide for x86 Linux, Mac OS/X or Windows. -+-------------------------------------------------+ -| * Download | -| | -| * `With a JIT Compiler`_ **(recommended!)** | -| * `With no JIT Compiler`_ | -| * `Sandboxed version`_ | -| * `Stackless version`_ | -| | -| * `Installing`_ (optional) | -| * `Building from source`_ | -+-------------------------------------------------+ +.. block:: + * Download + + * `With a JIT Compiler`_ **(recommended!)** + * `With no JIT Compiler`_ + * `Sandboxed version`_ + * `Stackless version`_ + + * `Installing`_ (optional) + * `Building from source`_ .. _`With a JIT Compiler`: From fijal at codespeak.net Wed Mar 10 17:12:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 17:12:11 +0100 (CET) Subject: [pypy-svn] r72070 - in pypy/extradoc/pypy.org: . js source Message-ID: <20100310161211.E6B43282BAD@codespeak.net> Author: fijal Date: Wed Mar 10 17:12:10 2010 New Revision: 72070 Added: pypy/extradoc/pypy.org/release.html pypy/extradoc/pypy.org/source/release.txt (contents, props changed) Modified: pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/js/detect.js pypy/extradoc/pypy.org/source/download.txt Log: Add a dummy download page Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Wed Mar 10 17:12:10 2010 @@ -152,13 +152,13 @@

  • Get the source code. The following packages contain the source at the same revision as the above binaries:

    Or you can checkout the current trunk using Subversion (the trunk usually works and is of course more up-to-date):

    -svn co http://codespeak.net/svn/pypy/trunk pypy-dist
    +svn co http://codespeak.net/svn/pypy/trunk pypy-trunk
     

    Windows users trying the tarballs are expected to use MSVC. The trunk version contains fixes to support MinGW32. More Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Wed Mar 10 17:12:10 2010 @@ -14,6 +14,7 @@ download_url = "download.html"; download_text = "Download page"; } + download_url = "release.html"; $("#main_download").attr('href', download_url); $("#main_download").text(download_text); }); Added: pypy/extradoc/pypy.org/release.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/release.html Wed Mar 10 17:12:10 2010 @@ -0,0 +1,75 @@ + + + + PyPy :: Release pending + + + + + + + + + + + + + + + +

    + +
    +
    +
    +

    Release pending

    +

    Meanwhile, you can try PyPy out from source

    +
    + +
    +
    +
    + + \ No newline at end of file Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Wed Mar 10 17:12:10 2010 @@ -212,6 +212,6 @@ .. _`sandboxing`: features.html#sandboxing .. _`stackless`: http://www.stackless.com/ .. _`greenlets`: http://codespeak.net/svn/greenlet/trunk/doc/greenlet.txt -.. _`pypy-1.2-src.tar.bz2`: download/pypy-1.2-src.tar.bz2 -.. _`pypy-1.2-src.zip`: download/pypy-1.2-src.zip +.. _`pypy-1.2-src.tar.bz2`: release.html +.. _`pypy-1.2-src.zip`: release.html .. _Subversion: http://subversion.tigris.org/ Added: pypy/extradoc/pypy.org/source/release.txt ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/source/release.txt Wed Mar 10 17:12:10 2010 @@ -0,0 +1,11 @@ +--- +layout: page +title: Release pending +--- + +Release is pending, please stay tuned +===================================== + +Meanwhile, you can try PyPy out from `source`_ + +.. _`source`: download.html#Building_from_source From fijal at codespeak.net Wed Mar 10 17:12:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 10 Mar 2010 17:12:56 +0100 (CET) Subject: [pypy-svn] r72071 - in pypy/extradoc/pypy.org: . source Message-ID: <20100310161256.5B054282BAD@codespeak.net> Author: fijal Date: Wed Mar 10 17:12:55 2010 New Revision: 72071 Modified: pypy/extradoc/pypy.org/release.html pypy/extradoc/pypy.org/source/release.txt Log: fix link Modified: pypy/extradoc/pypy.org/release.html ============================================================================== --- pypy/extradoc/pypy.org/release.html (original) +++ pypy/extradoc/pypy.org/release.html Wed Mar 10 17:12:55 2010 @@ -47,7 +47,7 @@

    Release pending

    -

    Meanwhile, you can try PyPy out from source

    +

    Meanwhile, you can try PyPy out from source

    -->
    - +
    Modified: pypy/extradoc/pypy.org/compat.html ============================================================================== --- pypy/extradoc/pypy.org/compat.html (original) +++ pypy/extradoc/pypy.org/compat.html Thu Mar 11 17:40:40 2010 @@ -40,7 +40,7 @@
    -->
    - +
  • Added: pypy/extradoc/pypy.org/contact.html ============================================================================== --- (empty file) +++ pypy/extradoc/pypy.org/contact.html Thu Mar 11 17:40:40 2010 @@ -0,0 +1,80 @@ + + + + PyPy :: Contact + + + + + + + + + + + + + + + +
    + +
    +
    +
    +

    Contact

    + +
    + +
    +
    +
    + + \ No newline at end of file Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Thu Mar 11 17:40:40 2010 @@ -40,7 +40,7 @@
    -->
    - +
    @@ -48,7 +48,10 @@

    Download and install

    Here are the various binaries of PyPy 1.2 that we provide for x86 Linux, -Mac OS/X or Windows.

    +Mac OS/X or Windows. This is the first release of PyPy containing JIT, hence +the main goal is to try this out and see how it works for you. We put +a lot of effort into making JIT a stable piece of software and we don't +observe crashes, however, please consider it a beta version to try things out.

    • Download
      • With a JIT Compiler (recommended!)
      • @@ -69,14 +72,14 @@
        • Linux binary
        • Mac OS/X binary
        • -
        • Windows binary (this version is alpha software!)
        • +
        • Windows binary

        If your CPU is really old, it may not have SSE2. In this case, you need to translate yourself with the option --jit-backend=x86-without-sse2.

        If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

        If you want to help us with implementing the 64-bit JIT backend, -contact us!

        +contact us!

    “No JIT” version

    @@ -97,7 +100,8 @@ version of PyPy yourself, here are hints.

    If you want to help us with finishing the implementation of the native 64-bit version (there are a few known issues, like missing code in -ctypes to implement calls to C functions), contact us.

    +ctypes to implement calls to C functions), contact us. In general +this version will more or less translate anywhere.

    “Sandbox” version

    @@ -115,7 +119,7 @@

    If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

    The native 64-bit version needs testing and careful reviewing; -contact us!

    +contact us!

    “Stackless” version

    @@ -158,13 +162,13 @@
     svn co http://codespeak.net/svn/pypy/trunk pypy-trunk
     
    -

    Windows users trying the tarballs are expected to use MSVC. +

    Windows users trying the zip file are expected to use MSVC. The trunk version contains fixes to support MinGW32. More information on our dev site.

  • Enter the goal directory:

    -cd pypy-dist/pypy/translator/goal
    +cd pypy-trunk/pypy/translator/goal
     
  • Run the translate.py script. Here are the common combinations Modified: pypy/extradoc/pypy.org/features.html ============================================================================== --- pypy/extradoc/pypy.org/features.html (original) +++ pypy/extradoc/pypy.org/features.html Thu Mar 11 17:40:40 2010 @@ -40,7 +40,7 @@

  • -->
    - +
    @@ -52,9 +52,9 @@ already accepted in main python in newer versions). It supports most of commonly used Python standard library modules. For known differences with CPython, see our compatibility page. If you are interested in -helping with 2.6, 2.7 or 3.x features, contact us!

    +helping with 2.6, 2.7 or 3.x features, contact us!

    PyPy 1.2 runs essentially only on Intel x86 (IA-32). On 64-bit platforms -you have to use the 32-bit compatibility mode, for now — or contact us +you have to use the 32-bit compatibility mode, for now — or contact us to help!

    Speed or memory usage?

    @@ -72,11 +72,25 @@ try to limit language features considered “unsafe”. Instead we replace all calls to external libraries (C or platform) with a stub that communicates with an external process handling the policy.

    -

    To run the sandboxed process, get a sandboxed pypy-c and run:

    +

    To run the sandboxed process, you need pypy-sandbox. You also need to +get the full sources (step 1 only). Run:

    -pypy_interact.py pypy-c-sandbox
    +cd pypy-trunk/pypy/translator/sandbox
    +pypy_interact.py path/to/pypy-sandbox
     
    -

    To read more about its features, go to our dev site.

    +

    You get a fully sandboxed interpreter, in its own filesystem hierarchy +(try os.listdir('/')). For example, you would run an untrusted +script as follows:

    +
    +mkdir virtualtmp
    +cp untrusted.py virtualtmp/
    +pypy_interact.py --tmp=virtualtmp pypy-sandbox /tmp/untrusted.py
    +
    +

    Note that the path /tmp/untrusted.py is a path inside the sandboxed +filesystem. You don't have to put untrusted.py in the real /tmp +directory at all.

    +

    To read more about its features, try pypy_interact.py --help or go to +our dev site.

    Stackless

    @@ -99,7 +113,7 @@
  • the Java backend: PyPy can run on the Java VM, but more care is needed to finish this project. (Requires the cli-jit branch for now.) Writing a backend for our high-level JIT compiler would be -excellent. Contact us!
  • +excellent. Contact us!
  • Other languages: available in a separate part of the repository, we implemented other languages too: Prolog (almost complete), as well as Smalltalk, JavaScript, Io, Scheme and Gameboy.
  • Modified: pypy/extradoc/pypy.org/index.html ============================================================================== --- pypy/extradoc/pypy.org/index.html (original) +++ pypy/extradoc/pypy.org/index.html Thu Mar 11 17:40:40 2010 @@ -40,7 +40,7 @@
    -->
    - +
    Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Thu Mar 11 17:40:40 2010 @@ -8,7 +8,7 @@ download_url = 'download/pypy-1.2-win32.zip'; download_text = 'Download Windows i386 bin'; } else if (navigator.platform.indexOf('Mac') != 1) { - download_url = 'download/pypy-1.2-mac.tar.bz2'; + download_url = 'download/pypy-1.2-osx.tar.bz2'; downloat_text = 'Download Mac OS X 10.6 bin'; } else { download_url = "download.html"; Modified: pypy/extradoc/pypy.org/release.html ============================================================================== --- pypy/extradoc/pypy.org/release.html (original) +++ pypy/extradoc/pypy.org/release.html Thu Mar 11 17:40:40 2010 @@ -40,7 +40,7 @@
    -->
    - +
    From arigo at codespeak.net Thu Mar 11 17:47:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 17:47:49 +0100 (CET) Subject: [pypy-svn] r72114 - pypy/extradoc/pypy.org/source Message-ID: <20100311164749.87DDE282BD5@codespeak.net> Author: arigo Date: Thu Mar 11 17:47:47 2010 New Revision: 72114 Modified: pypy/extradoc/pypy.org/source/download.txt pypy/extradoc/pypy.org/source/features.txt Log: Add links (most of them not here yet). Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Thu Mar 11 17:47:47 2010 @@ -34,9 +34,13 @@ them do, nowadays), as well as on any `x86-64`_ machine in the 32-bit compatibility mode. -* Linux binary -* Mac OS/X binary -* Windows binary +* `Linux binary`__ +* `Mac OS/X binary`__ +* `Windows binary`__ + +.. __: http://pypy.org/download/pypy-1.2-linux.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-osx.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-win.zip If your CPU is really old, it may not have SSE2. In this case, you need to translate_ yourself with the option ``--jit-backend=x86-without-sse2``. @@ -59,14 +63,18 @@ This version still has a few advantages over the JIT Compiler version. Notably, for Python programs that require large amounts of memory (at -least a few hundred MBs), the following version of ``pypy-c`` runs them +least a few hundred MBs), the following version of ``pypy-nojit`` runs them by requiring generally 1.5x or 2x less memory than CPython. These binaries work on 32-bit `x86 (IA-32)`_ CPUs as well as `x86-64`_ CPUs in the 32-bit compatibility mode. -* Linux binary -* Mac OS/X binary -* Windows binary +* `Linux binary`__ +* `Mac OS/X binary`__ +* `Windows binary`__ + +.. __: http://pypy.org/download/pypy-nojit-1.2-linux.tar.bz2 +.. __: http://pypy.org/download/pypy-nojit-1.2-osx.tar.bz2 +.. __: http://pypy.org/download/pypy-nojit-1.2-win.zip If your CPU is a 64-bit machine and you want to translate_ a 32-bit version of PyPy yourself, `here are hints`_. @@ -86,9 +94,13 @@ binaries work on 32-bit `x86 (IA-32)`_ CPUs as well as `x86-64`_ CPUs in the 32-bit compatibility mode. -* Linux binary -* Mac OS/X binary -* Windows binary +* `Linux binary`__ +* `Mac OS/X binary`__ +* `Windows binary`__ + +.. __: http://pypy.org/download/pypy-sandbox-1.2-linux.bz2 +.. __: http://pypy.org/download/pypy-sandbox-1.2-osx.bz2 +.. __: http://pypy.org/download/pypy-sandbox-1.2-win.zip It is also possible to translate_ a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -110,9 +122,13 @@ binaries work on 32-bit `x86 (IA-32)`_ CPUs as well as `x86-64`_ CPUs in the 32-bit compatibility mode. -* Linux binary -* Mac OS/X binary -* Windows binary +* `Linux binary`__ +* `Mac OS/X binary`__ +* `Windows binary`__ + +.. __: http://pypy.org/download/pypy-stackless-1.2-linux.tar.bz2 +.. __: http://pypy.org/download/pypy-stackless-1.2-osx.tar.bz2 +.. __: http://pypy.org/download/pypy-stackless-1.2-win.zip It is not possible right now to combine Stackless features with the JIT. @@ -129,7 +145,7 @@ uncompressed, they run in-place. On Linux or Mac OS/X, they can also be installed by manually moving the files in the following directories:: - /usr/bin/pypy-c + /usr/bin/pypy /usr/share/pypy-1.2/lib-python/* /usr/share/pypy-1.2/pypy/* Modified: pypy/extradoc/pypy.org/source/features.txt ============================================================================== --- pypy/extradoc/pypy.org/source/features.txt (original) +++ pypy/extradoc/pypy.org/source/features.txt Thu Mar 11 17:47:47 2010 @@ -92,9 +92,9 @@ PyPy has many secondary features and semi-independent projects. We will mention here: -* **the .NET backend:** you get a version of ``pypy-c`` that runs +* **the .NET backend:** you get a version of ``pypy-net`` that runs natively in the .NET/CLI VM. Of particular interest is `the cli-jit - branch`_, in which you can make a version of ``pypy-c`` which also + branch`_, in which you can make a version of ``pypy-net`` which also contains a high-level JIT compiler (it compiles your Python programs Just in Time into CLR bytecodes, which are in turn compiled natively by the VM). From arigo at codespeak.net Thu Mar 11 17:56:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 17:56:53 +0100 (CET) Subject: [pypy-svn] r72115 - pypy/extradoc/pypy.org/source Message-ID: <20100311165653.D7399282BD7@codespeak.net> Author: arigo Date: Thu Mar 11 17:56:52 2010 New Revision: 72115 Modified: pypy/extradoc/pypy.org/source/download.txt Log: Update the links. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Thu Mar 11 17:56:52 2010 @@ -72,9 +72,9 @@ * `Mac OS/X binary`__ * `Windows binary`__ -.. __: http://pypy.org/download/pypy-nojit-1.2-linux.tar.bz2 -.. __: http://pypy.org/download/pypy-nojit-1.2-osx.tar.bz2 -.. __: http://pypy.org/download/pypy-nojit-1.2-win.zip +.. __: http://pypy.org/download/pypy-1.2-linux-nojit.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-osx-nojit.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-win-nojit.zip If your CPU is a 64-bit machine and you want to translate_ a 32-bit version of PyPy yourself, `here are hints`_. @@ -98,9 +98,9 @@ * `Mac OS/X binary`__ * `Windows binary`__ -.. __: http://pypy.org/download/pypy-sandbox-1.2-linux.bz2 -.. __: http://pypy.org/download/pypy-sandbox-1.2-osx.bz2 -.. __: http://pypy.org/download/pypy-sandbox-1.2-win.zip +.. __: http://pypy.org/download/pypy-1.2-linux-sandbox.bz2 +.. __: http://pypy.org/download/pypy-1.2-osx-sandbox.bz2 +.. __: http://pypy.org/download/pypy-1.2-win-sandbox.zip It is also possible to translate_ a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -126,9 +126,9 @@ * `Mac OS/X binary`__ * `Windows binary`__ -.. __: http://pypy.org/download/pypy-stackless-1.2-linux.tar.bz2 -.. __: http://pypy.org/download/pypy-stackless-1.2-osx.tar.bz2 -.. __: http://pypy.org/download/pypy-stackless-1.2-win.zip +.. __: http://pypy.org/download/pypy-1.2-linux-stackless.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-osx-stackless.tar.bz2 +.. __: http://pypy.org/download/pypy-1.2-win-stackless.zip It is not possible right now to combine Stackless features with the JIT. @@ -158,10 +158,13 @@ ------------------------------- 1. Get the source code. The following packages contain the source at - the same revision as the above binaries: + the same revision as the above binaries (these are svn exports): - * pypy-1.2-src.tar.bz2 (sources, Unix line endings) - * pypy-1.2-src.zip (sources, Windows line endings) + * `pypy-1.2-src.tar.bz2`__ (sources, Unix line endings) + * `pypy-1.2-src.zip`__ (sources, Windows line endings) + + .. __: http://pypy.org/download/pypy-1.2-src.tar.bz2 + .. __: http://pypy.org/download/pypy-1.2-src.zip Or you can checkout the current trunk using Subversion_ (the trunk usually works and is of course more up-to-date):: From fijal at codespeak.net Thu Mar 11 18:20:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 18:20:51 +0100 (CET) Subject: [pypy-svn] r72116 - pypy/extradoc/pypy.org Message-ID: <20100311172051.93CFA51054@codespeak.net> Author: fijal Date: Thu Mar 11 18:20:50 2010 New Revision: 72116 Modified: pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/features.html Log: update html Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Thu Mar 11 18:20:50 2010 @@ -70,9 +70,9 @@ them do, nowadays), as well as on any x86-64 machine in the 32-bit compatibility mode.

    If your CPU is really old, it may not have SSE2. In this case, you need to translate yourself with the option --jit-backend=x86-without-sse2.

    @@ -81,20 +81,20 @@

    If you want to help us with implementing the 64-bit JIT backend, contact us!

    -
    +

    “No JIT” version

    WARNING! Unless you really want to try this out, we recommend the JIT version.

    This version still has a few advantages over the JIT Compiler version. Notably, for Python programs that require large amounts of memory (at -least a few hundred MBs), the following version of pypy-c runs them +least a few hundred MBs), the following version of pypy-nojit runs them by requiring generally 1.5x or 2x less memory than CPython. These binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs in the 32-bit compatibility mode.

    If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

    @@ -109,9 +109,9 @@ binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs in the 32-bit compatibility mode.

    It is also possible to translate a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -121,15 +121,15 @@

    The native 64-bit version needs testing and careful reviewing; contact us!

    -
    +

    “Stackless” version

    Provides Stackless extensions, as well as greenlets. These binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs in the 32-bit compatibility mode.

    It is not possible right now to combine Stackless features with the JIT.

    If your CPU is a 64-bit machine and you want to translate a 32-bit @@ -142,7 +142,7 @@ uncompressed, they run in-place. On Linux or Mac OS/X, they can also be installed by manually moving the files in the following directories:

    -/usr/bin/pypy-c
    +/usr/bin/pypy
     /usr/share/pypy-1.2/lib-python/*
     /usr/share/pypy-1.2/pypy/*
     
    @@ -152,10 +152,10 @@

    Building from source

    1. Get the source code. The following packages contain the source at -the same revision as the above binaries:

      +the same revision as the above binaries (these are svn exports):

        -
      • pypy-1.2-src.tar.bz2 (sources, Unix line endings)
      • -
      • pypy-1.2-src.zip (sources, Windows line endings)
      • +
      • pypy-1.2-src.tar.bz2 (sources, Unix line endings)
      • +
      • pypy-1.2-src.zip (sources, Windows line endings)

      Or you can checkout the current trunk using Subversion (the trunk usually works and is of course more up-to-date):

      Modified: pypy/extradoc/pypy.org/features.html ============================================================================== --- pypy/extradoc/pypy.org/features.html (original) +++ pypy/extradoc/pypy.org/features.html Thu Mar 11 18:20:50 2010 @@ -104,9 +104,9 @@

      PyPy has many secondary features and semi-independent projects. We will mention here:

        -
      • the .NET backend: you get a version of pypy-c that runs +
      • the .NET backend: you get a version of pypy-net that runs natively in the .NET/CLI VM. Of particular interest is the cli-jit -branch, in which you can make a version of pypy-c which also +branch, in which you can make a version of pypy-net which also contains a high-level JIT compiler (it compiles your Python programs Just in Time into CLR bytecodes, which are in turn compiled natively by the VM).
      • From fijal at codespeak.net Thu Mar 11 18:33:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 18:33:31 +0100 (CET) Subject: [pypy-svn] r72117 - in pypy/extradoc/pypy.org: . js source Message-ID: <20100311173331.62C40282BDD@codespeak.net> Author: fijal Date: Thu Mar 11 18:33:29 2010 New Revision: 72117 Removed: pypy/extradoc/pypy.org/release.html pypy/extradoc/pypy.org/source/release.txt Modified: pypy/extradoc/pypy.org/js/detect.js Log: Remove placeholder Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Thu Mar 11 18:33:29 2010 @@ -14,7 +14,6 @@ download_url = "download.html"; download_text = "Download page"; } - download_url = "release.html"; $("#main_download").attr('href', download_url); $("#main_download").text(download_text); }); From fijal at codespeak.net Thu Mar 11 18:36:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 18:36:59 +0100 (CET) Subject: [pypy-svn] r72118 - pypy/extradoc/pypy.org/js Message-ID: <20100311173659.E543C282BDD@codespeak.net> Author: fijal Date: Thu Mar 11 18:36:58 2010 New Revision: 72118 Modified: pypy/extradoc/pypy.org/js/detect.js Log: fix link Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Thu Mar 11 18:36:58 2010 @@ -2,7 +2,7 @@ $(document).ready(function() { var download_url, download_text; if (navigator.platform.indexOf('Linux') != -1) { - download_url = 'download/pypy-1.2.tar.bz2'; + download_url = 'download/pypy-1.2-linux.tar.bz2'; download_text = 'Download linux i386 bin'; } else if (navigator.platform.indexOf('Win') != -1) { download_url = 'download/pypy-1.2-win32.zip'; From arigo at codespeak.net Thu Mar 11 18:47:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 18:47:15 +0100 (CET) Subject: [pypy-svn] r72119 - pypy/extradoc/pypy.org/source Message-ID: <20100311174715.A6AFE282BDD@codespeak.net> Author: arigo Date: Thu Mar 11 18:47:14 2010 New Revision: 72119 Modified: pypy/extradoc/pypy.org/source/TODO Log: Update by removing tasks done. Modified: pypy/extradoc/pypy.org/source/TODO ============================================================================== --- pypy/extradoc/pypy.org/source/TODO (original) +++ pypy/extradoc/pypy.org/source/TODO Thu Mar 11 18:47:14 2010 @@ -1,16 +1,6 @@ -* kill "alpha software" after Windows. Add "it's all beta software" - somewhere. Fix the box at the start of download.txt. - * svn cp release/1.2.x release/1.2.0 * svn cp release/1.2.x dist * finish the release announcement pypy/doc/release-1.2.0.txt -* binary tarballs: use pypy/tool/package.py on Linux and Mac OS/X, - make it manually on Windows for now - -* source tarballs: make them manually? - -* move the tarballs to http://codespeak.net/download/pypy/ - * recompute the html files on codespeak, from dist and from trunk From arigo at codespeak.net Thu Mar 11 18:55:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 18:55:03 +0100 (CET) Subject: [pypy-svn] r72120 - pypy/extradoc/pypy.org/source Message-ID: <20100311175503.D9769282BDD@codespeak.net> Author: arigo Date: Thu Mar 11 18:55:02 2010 New Revision: 72120 Modified: pypy/extradoc/pypy.org/source/download.txt Log: Rename to win32. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Thu Mar 11 18:55:02 2010 @@ -40,7 +40,7 @@ .. __: http://pypy.org/download/pypy-1.2-linux.tar.bz2 .. __: http://pypy.org/download/pypy-1.2-osx.tar.bz2 -.. __: http://pypy.org/download/pypy-1.2-win.zip +.. __: http://pypy.org/download/pypy-1.2-win32.zip If your CPU is really old, it may not have SSE2. In this case, you need to translate_ yourself with the option ``--jit-backend=x86-without-sse2``. @@ -74,7 +74,7 @@ .. __: http://pypy.org/download/pypy-1.2-linux-nojit.tar.bz2 .. __: http://pypy.org/download/pypy-1.2-osx-nojit.tar.bz2 -.. __: http://pypy.org/download/pypy-1.2-win-nojit.zip +.. __: http://pypy.org/download/pypy-1.2-win32-nojit.zip If your CPU is a 64-bit machine and you want to translate_ a 32-bit version of PyPy yourself, `here are hints`_. @@ -100,7 +100,7 @@ .. __: http://pypy.org/download/pypy-1.2-linux-sandbox.bz2 .. __: http://pypy.org/download/pypy-1.2-osx-sandbox.bz2 -.. __: http://pypy.org/download/pypy-1.2-win-sandbox.zip +.. __: http://pypy.org/download/pypy-1.2-win32-sandbox.zip It is also possible to translate_ a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -128,7 +128,7 @@ .. __: http://pypy.org/download/pypy-1.2-linux-stackless.tar.bz2 .. __: http://pypy.org/download/pypy-1.2-osx-stackless.tar.bz2 -.. __: http://pypy.org/download/pypy-1.2-win-stackless.zip +.. __: http://pypy.org/download/pypy-1.2-win32-stackless.zip It is not possible right now to combine Stackless features with the JIT. From fijal at codespeak.net Thu Mar 11 18:56:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 18:56:08 +0100 (CET) Subject: [pypy-svn] r72121 - pypy/extradoc/pypy.org Message-ID: <20100311175608.78725282BDD@codespeak.net> Author: fijal Date: Thu Mar 11 18:56:07 2010 New Revision: 72121 Modified: pypy/extradoc/pypy.org/download.html Log: update html Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Thu Mar 11 18:56:07 2010 @@ -72,7 +72,7 @@

        If your CPU is really old, it may not have SSE2. In this case, you need to translate yourself with the option --jit-backend=x86-without-sse2.

        @@ -94,7 +94,7 @@

        If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

        @@ -111,7 +111,7 @@

        It is also possible to translate a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -129,7 +129,7 @@

        It is not possible right now to combine Stackless features with the JIT.

        If your CPU is a 64-bit machine and you want to translate a 32-bit From arigo at codespeak.net Thu Mar 11 18:58:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 18:58:33 +0100 (CET) Subject: [pypy-svn] r72122 - pypy/extradoc/pypy.org/source/website/js Message-ID: <20100311175833.63A21282BDD@codespeak.net> Author: arigo Date: Thu Mar 11 18:58:31 2010 New Revision: 72122 Modified: pypy/extradoc/pypy.org/source/website/js/detect.js Log: Fix the links. Modified: pypy/extradoc/pypy.org/source/website/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/source/website/js/detect.js (original) +++ pypy/extradoc/pypy.org/source/website/js/detect.js Thu Mar 11 18:58:31 2010 @@ -2,13 +2,13 @@ $(document).ready(function() { var download_url, download_text; if (navigator.platform.indexOf('Linux') != -1) { - download_url = 'download/pypy-1.2.tar.bz2'; + download_url = 'download/pypy-1.2-linux.tar.bz2'; download_text = 'Download linux x86 bin'; } else if (navigator.platform.indexOf('Windows') != -1) { download_url = 'download/pypy-1.2-win32.zip'; download_text = 'Download Windows bin'; } else if (navigator.platform.indexOf('Mac') != 1) { - download_url = 'download/pypy-1.2-mac.tar.bz2'; + download_url = 'download/pypy-1.2-osx.tar.bz2'; downloat_text = 'Download Mac OS X 10.6 bin'; } else { return; From fijal at codespeak.net Thu Mar 11 19:01:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 19:01:11 +0100 (CET) Subject: [pypy-svn] r72123 - pypy/extradoc/pypy.org/source/website Message-ID: <20100311180111.E7DD0282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 19:01:10 2010 New Revision: 72123 Removed: pypy/extradoc/pypy.org/source/website/ Log: this dir is pointless From arigo at codespeak.net Thu Mar 11 19:15:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 19:15:02 +0100 (CET) Subject: [pypy-svn] r72124 - pypy/extradoc/pypy.org/source Message-ID: <20100311181502.E980C282BDA@codespeak.net> Author: arigo Date: Thu Mar 11 19:15:01 2010 New Revision: 72124 Modified: pypy/extradoc/pypy.org/source/download.txt Log: Clarify. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Thu Mar 11 19:15:01 2010 @@ -143,9 +143,9 @@ All versions are packaged in a ``tar.bz2`` or ``zip`` file. When uncompressed, they run in-place. On Linux or Mac OS/X, they can also be -installed by manually moving the files in the following directories:: +installed by manually moving the files:: - /usr/bin/pypy + /usr/bin/pypy # or pypy-nojit etc. /usr/share/pypy-1.2/lib-python/* /usr/share/pypy-1.2/pypy/* From fijal at codespeak.net Thu Mar 11 19:18:38 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 19:18:38 +0100 (CET) Subject: [pypy-svn] r72125 - pypy/trunk/dotviewer Message-ID: <20100311181838.0BED6282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 19:18:37 2010 New Revision: 72125 Modified: pypy/trunk/dotviewer/drawgraph.py Log: Kill 2.3 compatibility Modified: pypy/trunk/dotviewer/drawgraph.py ============================================================================== --- pypy/trunk/dotviewer/drawgraph.py (original) +++ pypy/trunk/dotviewer/drawgraph.py Thu Mar 11 19:18:37 2010 @@ -658,12 +658,3 @@ self.renderer.textzones.append((x, y, w, h, word)) x += w - -try: - sum # 2.3 only -except NameError: - def sum(lst): - total = 0 - for item in lst: - total += lst - return total From arigo at codespeak.net Thu Mar 11 19:22:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 11 Mar 2010 19:22:30 +0100 (CET) Subject: [pypy-svn] r72126 - pypy/extradoc/pypy.org/js Message-ID: <20100311182230.3A72D282BDA@codespeak.net> Author: arigo Date: Thu Mar 11 19:22:28 2010 New Revision: 72126 Modified: pypy/extradoc/pypy.org/js/detect.js Log: Say x86 instead of i386. Modified: pypy/extradoc/pypy.org/js/detect.js ============================================================================== --- pypy/extradoc/pypy.org/js/detect.js (original) +++ pypy/extradoc/pypy.org/js/detect.js Thu Mar 11 19:22:28 2010 @@ -3,10 +3,10 @@ var download_url, download_text; if (navigator.platform.indexOf('Linux') != -1) { download_url = 'download/pypy-1.2-linux.tar.bz2'; - download_text = 'Download linux i386 bin'; + download_text = 'Download linux x86 bin'; } else if (navigator.platform.indexOf('Win') != -1) { download_url = 'download/pypy-1.2-win32.zip'; - download_text = 'Download Windows i386 bin'; + download_text = 'Download Windows x86 bin'; } else if (navigator.platform.indexOf('Mac') != 1) { download_url = 'download/pypy-1.2-osx.tar.bz2'; downloat_text = 'Download Mac OS X 10.6 bin'; From getxsick at codespeak.net Thu Mar 11 19:28:35 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 19:28:35 +0100 (CET) Subject: [pypy-svn] r72127 - pypy/build/ubuntu/debian Message-ID: <20100311182835.A3F3A282BDA@codespeak.net> Author: getxsick Date: Thu Mar 11 19:28:34 2010 New Revision: 72127 Modified: pypy/build/ubuntu/debian/compat Log: update debhelper dependence Modified: pypy/build/ubuntu/debian/compat ============================================================================== --- pypy/build/ubuntu/debian/compat (original) +++ pypy/build/ubuntu/debian/compat Thu Mar 11 19:28:34 2010 @@ -1 +1 @@ -6 +7 From fijal at codespeak.net Thu Mar 11 19:42:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 19:42:53 +0100 (CET) Subject: [pypy-svn] r72128 - in pypy/trunk/pypy/jit/tool: . test Message-ID: <20100311184253.7E33D282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 19:42:46 2010 New Revision: 72128 Modified: pypy/trunk/pypy/jit/tool/otherviewer.py pypy/trunk/pypy/jit/tool/test/test_otherviewer.py Log: Improve otherviewer, fix tests. For a very large files, you need to provide a cutoff, otherwise dot will segfault Modified: pypy/trunk/pypy/jit/tool/otherviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/otherviewer.py Thu Mar 11 19:42:46 2010 @@ -11,6 +11,7 @@ from pypy.translator.tool.graphpage import GraphPage from pypy.translator.tool.make_dot import DotGen from pypy.tool import logparser +from pypy.tool import progressbar class SubPage(GraphPage): def compute(self, graph): @@ -56,6 +57,21 @@ dotgen.emit_node(self.name(), label=self.header, shape='box', fillcolor=get_gradient_color(self.ratio)) + def get_content(self): + return self._content + + def set_content(self, content): + self._content = content + groups = re.findall('Guard(\d+)', content) + if not groups: + self.first_guard = -1 + self.last_guard = -1 + else: + self.first_guard = int(groups[0]) + self.last_guard = int(groups[-1]) + + content = property(get_content, set_content) + def get_gradient_color(ratio): if ratio == 0: return 'white' @@ -74,7 +90,6 @@ # from yellow (ratio=0) to green (ratio=-1) return '#%02XFF00' % (int((1.0+ratio)*255.5),) - class FinalBlock(BasicBlock): def __init__(self, content, target): self.target = target @@ -117,8 +132,11 @@ dotgen.emit_edge(self.name(), self.left.name()) dotgen.emit_edge(self.name(), self.right.name()) -def split_one_loop(allloops, guard_s, guard_content, lineno): - for i, loop in enumerate(allloops): +def split_one_loop(real_loops, guard_s, guard_content, lineno, no, allloops): + for i in range(len(allloops) - 1, -1, -1): + loop = allloops[i] + if no < loop.first_guard or no > loop.last_guard: + continue content = loop.content pos = content.find(guard_s + '>') if pos != -1: @@ -127,33 +145,57 @@ assert newpos != -1 if oldpos == -1: oldpos = len(content) - allloops[i] = Block(content[:oldpos], - FinalBlock(content[oldpos:], None), - FinalBlock(content[newpos + 1:oldpos] + "\n" + - guard_content, None)) - allloops[i].guard_s = guard_s - allloops[i].startlineno = loop.startlineno - allloops[i].left.startlineno = loop.startlineno + content.count("\n", 0, pos) - allloops[i].right.startlineno = lineno + if isinstance(loop, Block): + left = Block(content[oldpos:], loop.left, loop.right) + else: + left = FinalBlock(content[oldpos:], None) + right = FinalBlock(guard_content, None) + mother = Block(content[:oldpos], len(allloops), len(allloops) + 1) + allloops[i] = mother + allloops.append(left) + allloops.append(right) + if hasattr(loop, 'loop_no'): + real_loops[loop.loop_no] = mother + mother.loop_no = loop.loop_no + mother.guard_s = guard_s + mother.startlineno = loop.startlineno + left.startlineno = loop.startlineno + content.count("\n", 0, pos) + right.startlineno = lineno + return + else: + raise Exception("Did not find") + +MAX_LOOPS = 300 def splitloops(loops): real_loops = [] counter = 1 - for loop in loops: + bar = progressbar.ProgressBar(color='blue') + single_percent = len(loops) / 100 + allloops = [] + for i, loop in enumerate(loops): + if i > MAX_LOOPS: + return real_loops, allloops + if single_percent and i % single_percent == 0: + bar.render(i / single_percent) firstline = loop[:loop.find("\n")] m = re.match('# Loop (\d+)', firstline) if m: no = int(m.group(1)) assert len(real_loops) == no - real_loops.append(FinalBlock(loop, None)) - real_loops[-1].startlineno = counter + _loop = FinalBlock(loop, None) + real_loops.append(_loop) + _loop.startlineno = counter + _loop.loop_no = no + allloops.append(_loop) else: m = re.search("bridge out of Guard (\d+)", firstline) assert m guard_s = 'Guard' + m.group(1) - split_one_loop(real_loops, guard_s, loop, counter) + split_one_loop(real_loops, guard_s, loop, counter, + int(m.group(1)), allloops) counter += loop.count("\n") + 2 - return real_loops + return real_loops, allloops def postprocess_loop(loop, loops, memo): if loop in memo: @@ -184,7 +226,11 @@ loop.content = "Logfile at %d" % loop.startlineno loop.postprocess(loops, memo) -def postprocess(loops): +def postprocess(loops, allloops): + for loop in allloops: + if isinstance(loop, Block): + loop.left = allloops[loop.left] + loop.right = allloops[loop.right] memo = set() for loop in loops: postprocess_loop(loop, loops, memo) @@ -192,8 +238,8 @@ def main(loopfile, view=True): log = logparser.parse_log_file(loopfile) loops = logparser.extract_category(log, "jit-log-opt-") - allloops = splitloops(loops) - postprocess(allloops) + real_loops, allloops = splitloops(loops) + postprocess(real_loops, allloops) if view: Page(allloops).display() Modified: pypy/trunk/pypy/jit/tool/test/test_otherviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/test/test_otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/test/test_otherviewer.py Thu Mar 11 19:42:46 2010 @@ -38,15 +38,21 @@ p60 = getfield_gc(p4, descr=) guard_nonnull(p60, descr=) [p0, p1] """), None)] - split_one_loop(real_loops, 'Guard5', 'extra', 1) - assert isinstance(real_loops[1], Block) - assert real_loops[1].content.endswith('p1]') - assert real_loops[1].left.content == '' - assert real_loops[1].right.content.startswith('guard_nonnull') + real_loops[0].loop_no = 0 + real_loops[1].loop_no = 1 + allloops = real_loops[:] + split_one_loop(real_loops, 'Guard5', 'extra', 1, 5, allloops) + loop = real_loops[1] + assert isinstance(loop, Block) + assert loop.content.endswith('p1]') + loop.left = allloops[loop.left] + loop.right = allloops[loop.right] + assert loop.left.content == '' + assert loop.right.content == 'extra' def test_postparse(self): real_loops = [FinalBlock("debug_merge_point(' #40 POP_TOP')", None)] - postprocess(real_loops) + postprocess(real_loops, real_loops[:]) assert real_loops[0].header.startswith("_runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357") def test_load_actual(self): From fijal at codespeak.net Thu Mar 11 20:08:24 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 20:08:24 +0100 (CET) Subject: [pypy-svn] r72129 - pypy/extradoc/planning Message-ID: <20100311190824.7F888282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 20:08:22 2010 New Revision: 72129 Modified: pypy/extradoc/planning/jit.txt Log: mention an item Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Thu Mar 11 20:08:22 2010 @@ -29,6 +29,13 @@ - int_add_ovf(x, 0) guard_overflow is 20% of all int_add_ovf, not much overall, but probably worth attacking +- think about such example: + + http://paste.pocoo.org/show/188520/ + + this will compile new assembler path for each new type, even though that's + overspecialization since in this particular case it's not relevant. + Python interpreter: - goal: on average <=5 guards per original bytecode. From fijal at codespeak.net Thu Mar 11 20:09:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 20:09:17 +0100 (CET) Subject: [pypy-svn] r72130 - pypy/extradoc/planning Message-ID: <20100311190917.716B4282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 20:09:16 2010 New Revision: 72130 Modified: pypy/extradoc/planning/jit.txt Log: try to be more verbose Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Thu Mar 11 20:09:16 2010 @@ -35,6 +35,8 @@ this will compile new assembler path for each new type, even though that's overspecialization since in this particular case it's not relevant. + This is treated as a megamorphic call (promotion of w_self in typeobject.py) + while in fact it is not. Python interpreter: From getxsick at codespeak.net Thu Mar 11 20:59:24 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 20:59:24 +0100 (CET) Subject: [pypy-svn] r72131 - pypy/build/ubuntu/debian Message-ID: <20100311195924.A91CD282BDA@codespeak.net> Author: getxsick Date: Thu Mar 11 20:59:23 2010 New Revision: 72131 Modified: pypy/build/ubuntu/debian/copyright Log: remove lost GPL license Modified: pypy/build/ubuntu/debian/copyright ============================================================================== --- pypy/build/ubuntu/debian/copyright (original) +++ pypy/build/ubuntu/debian/copyright Thu Mar 11 20:59:23 2010 @@ -265,4 +265,3 @@ , Sylvain Th?nault and Chris Lamb The Debian packaging is (C) 2010 Bartosz Skowron -The package is licensed under the GPL, see `/usr/share/common-licenses/GPL'. From fijal at codespeak.net Thu Mar 11 21:02:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 21:02:55 +0100 (CET) Subject: [pypy-svn] r72132 - pypy/trunk/pypy/jit/tool Message-ID: <20100311200255.2F820282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 21:02:52 2010 New Revision: 72132 Modified: pypy/trunk/pypy/jit/tool/otherviewer.py Log: minor improvements to otherviewer Modified: pypy/trunk/pypy/jit/tool/otherviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/otherviewer.py Thu Mar 11 21:02:52 2010 @@ -223,7 +223,13 @@ loop.ratio = opsno else: loop.ratio = float(opsno) / bcodes - loop.content = "Logfile at %d" % loop.startlineno + content = loop.content + lines = content.split("\n") + if len(lines) > 100: + lines = lines[100:] + ["%d more lines..." % (len(lines) - 100)] + for i, line in enumerate(lines): + lines[i] = re.sub("\[.*\]", "", line) + loop.content = "Logfile at %d\n" % loop.startlineno + "\n".join(lines) loop.postprocess(loops, memo) def postprocess(loops, allloops): From cfbolz at codespeak.net Thu Mar 11 21:03:17 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Mar 2010 21:03:17 +0100 (CET) Subject: [pypy-svn] r72133 - pypy/extradoc/planning/1.2 Message-ID: <20100311200317.5CA39282BDA@codespeak.net> Author: cfbolz Date: Thu Mar 11 21:03:10 2010 New Revision: 72133 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: fix a few wordings Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Thu Mar 11 21:03:10 2010 @@ -3,9 +3,9 @@ ============================ We are pleased to announce PyPy's 1.2 release. -This 1.2 is a major milestone and it is +This version 1.2 is a major milestone and it is the first release to ship a `Just in time compiler`_ that is known to speed -up some real-world python programs. The main theme for the 1.2 release is +up some real-world Python programs. The main theme for the 1.2 release is **speed**. The JIT is stable and we don't observe crashes. @@ -15,7 +15,7 @@ Highlights: -* JIT compiler. +* The JIT compiler. * Various interpreter optimizations that improve performance as well as help save memory. Read our `various`_ `blog`_ `posts`_ about achievements. @@ -28,9 +28,10 @@ * Introducing Ubuntu packages on `PPA`_, done by `Bartosz Skowron`_. -Known JIT problems (or why you should consider this beta software): +Known JIT problems (or why you should consider this beta software) are: -* Only 32bit x86 for now, we're looking for help with other platforms. +* The only supported platform is 32bit x86 for now, we're looking for help with + other platforms. * It is still memory-hungry. There is no limit on the amount of RAM that the assembler can consume; it is thus possible (although unlikely) that From fijal at codespeak.net Thu Mar 11 21:10:20 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 21:10:20 +0100 (CET) Subject: [pypy-svn] r72134 - pypy/trunk/pypy/objspace/std Message-ID: <20100311201020.16401282BDA@codespeak.net> Author: fijal Date: Thu Mar 11 21:09:54 2010 New Revision: 72134 Modified: pypy/trunk/pypy/objspace/std/typeobject.py Log: remove pointless decorators - jit will not unroll stuff without explicit safe_unroll Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Mar 11 21:09:54 2010 @@ -221,7 +221,6 @@ return None - @dont_look_inside def _lookup(w_self, key): space = w_self.space for w_class in w_self.mro_w: @@ -230,7 +229,6 @@ return w_value return None - @dont_look_inside def _lookup_where(w_self, key): # like lookup() but also returns the parent class in which the # attribute was found From getxsick at codespeak.net Thu Mar 11 21:52:30 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 21:52:30 +0100 (CET) Subject: [pypy-svn] r72135 - pypy/build/ubuntu/debian Message-ID: <20100311205230.BD641282BE0@codespeak.net> Author: getxsick Date: Thu Mar 11 21:52:28 2010 New Revision: 72135 Modified: pypy/build/ubuntu/debian/rules Log: remove BAT script from the package Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Thu Mar 11 21:52:28 2010 @@ -55,6 +55,7 @@ rm -f debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o + rm -f debian/pypy-lib/usr/share/pypy-1.2/lib-python/2.5.2/idlelib/idle.bat rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ install-arch: From fijal at codespeak.net Thu Mar 11 22:02:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:02:30 +0100 (CET) Subject: [pypy-svn] r72136 - pypy/trunk/pypy/objspace/std Message-ID: <20100311210230.7A61B282BE0@codespeak.net> Author: fijal Date: Thu Mar 11 22:02:28 2010 New Revision: 72136 Modified: pypy/trunk/pypy/objspace/std/typeobject.py Log: Experimental checkin - look inside _lookup_where. We only do that if we have a custom metaclass or a mixed old-new bases, so should not hurt too much Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Mar 11 22:02:28 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.objectmodel import current_object_addr_as_int, compute_hash from pypy.rlib.jit import hint, purefunction_promote, we_are_jitted -from pypy.rlib.jit import dont_look_inside, purefunction +from pypy.rlib.jit import dont_look_inside, purefunction, unroll_safe from pypy.rlib.rarithmetic import intmask, r_uint from copy_reg import _HEAPTYPE @@ -220,7 +220,7 @@ return w_value return None - + @unroll_safe def _lookup(w_self, key): space = w_self.space for w_class in w_self.mro_w: @@ -229,6 +229,7 @@ return w_value return None + @unroll_safe def _lookup_where(w_self, key): # like lookup() but also returns the parent class in which the # attribute was found From fijal at codespeak.net Thu Mar 11 22:08:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:08:22 +0100 (CET) Subject: [pypy-svn] r72137 - pypy/trunk/pypy/objspace/std Message-ID: <20100311210822.58A42282BF1@codespeak.net> Author: fijal Date: Thu Mar 11 22:08:20 2010 New Revision: 72137 Modified: pypy/trunk/pypy/objspace/std/typeobject.py Log: Apparently 72136 was a very bad idea (confirmed), revert Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Mar 11 22:08:20 2010 @@ -9,7 +9,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.objectmodel import current_object_addr_as_int, compute_hash from pypy.rlib.jit import hint, purefunction_promote, we_are_jitted -from pypy.rlib.jit import dont_look_inside, purefunction, unroll_safe +from pypy.rlib.jit import dont_look_inside, purefunction from pypy.rlib.rarithmetic import intmask, r_uint from copy_reg import _HEAPTYPE @@ -220,7 +220,7 @@ return w_value return None - @unroll_safe + def _lookup(w_self, key): space = w_self.space for w_class in w_self.mro_w: @@ -229,7 +229,6 @@ return w_value return None - @unroll_safe def _lookup_where(w_self, key): # like lookup() but also returns the parent class in which the # attribute was found From getxsick at codespeak.net Thu Mar 11 22:14:25 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 22:14:25 +0100 (CET) Subject: [pypy-svn] r72138 - pypy/build/ubuntu/debian Message-ID: <20100311211425.EAC3D282BF1@codespeak.net> Author: getxsick Date: Thu Mar 11 22:14:24 2010 New Revision: 72138 Modified: pypy/build/ubuntu/debian/pypy-doc.docs Log: remove redundant LICENSE file Modified: pypy/build/ubuntu/debian/pypy-doc.docs ============================================================================== --- pypy/build/ubuntu/debian/pypy-doc.docs (original) +++ pypy/build/ubuntu/debian/pypy-doc.docs Thu Mar 11 22:14:24 2010 @@ -1,3 +1,2 @@ pypy/doc/* README -LICENSE From fijal at codespeak.net Thu Mar 11 22:18:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:18:07 +0100 (CET) Subject: [pypy-svn] r72139 - pypy/trunk/pypy/interpreter Message-ID: <20100311211807.B67F6282BF1@codespeak.net> Author: fijal Date: Thu Mar 11 22:18:06 2010 New Revision: 72139 Modified: pypy/trunk/pypy/interpreter/nestedscope.py Log: avoid pointless copy in case we don't have anything to add Modified: pypy/trunk/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/trunk/pypy/interpreter/nestedscope.py (original) +++ pypy/trunk/pypy/interpreter/nestedscope.py Thu Mar 11 22:18:06 2010 @@ -101,7 +101,9 @@ if len(closure) != nfreevars: raise ValueError("code object received a closure with " "an unexpected number of free variables") - self.cells = [Cell() for i in range(ncellvars)] + closure + self.cells = [Cell() for i in range(ncellvars)] + if closure: + self.cells += closure def getclosure(self): if self.cells is None: From fijal at codespeak.net Thu Mar 11 22:19:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:19:30 +0100 (CET) Subject: [pypy-svn] r72140 - pypy/extradoc/planning Message-ID: <20100311211930.C9DF1282BF1@codespeak.net> Author: fijal Date: Thu Mar 11 22:19:29 2010 New Revision: 72140 Modified: pypy/extradoc/planning/jit.txt Log: Mention another issue Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Thu Mar 11 22:19:29 2010 @@ -38,6 +38,11 @@ This is treated as a megamorphic call (promotion of w_self in typeobject.py) while in fact it is not. +- a recurring theme: we allocate an array, fill it with items, allocate new + array, copy_items, forget about first one. Would be cool to know that for + this case and some other cases, the static refcount can only be 1, so we + can optimize away the copy. + Python interpreter: - goal: on average <=5 guards per original bytecode. From fijal at codespeak.net Thu Mar 11 22:27:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:27:40 +0100 (CET) Subject: [pypy-svn] r72141 - pypy/trunk/pypy/jit/tool Message-ID: <20100311212740.B9C17282BF1@codespeak.net> Author: fijal Date: Thu Mar 11 22:27:39 2010 New Revision: 72141 Modified: pypy/trunk/pypy/jit/tool/otherviewer.py Log: Fix Modified: pypy/trunk/pypy/jit/tool/otherviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/otherviewer.py Thu Mar 11 22:27:39 2010 @@ -166,6 +166,7 @@ raise Exception("Did not find") MAX_LOOPS = 300 +LINE_CUTOFF = 300 def splitloops(loops): real_loops = [] @@ -225,8 +226,8 @@ loop.ratio = float(opsno) / bcodes content = loop.content lines = content.split("\n") - if len(lines) > 100: - lines = lines[100:] + ["%d more lines..." % (len(lines) - 100)] + if len(lines) > LINE_CUTOFF: + lines = lines[:LINE_CUTOFF] + ["%d more lines..." % (len(lines) - LINE_CUTOFF)] for i, line in enumerate(lines): lines[i] = re.sub("\[.*\]", "", line) loop.content = "Logfile at %d\n" % loop.startlineno + "\n".join(lines) From getxsick at codespeak.net Thu Mar 11 22:43:36 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 22:43:36 +0100 (CET) Subject: [pypy-svn] r72142 - pypy/trunk/lib-python/2.5.2/plat-irix5 Message-ID: <20100311214336.6DD68282BF1@codespeak.net> Author: getxsick Date: Thu Mar 11 22:43:35 2010 New Revision: 72142 Modified: pypy/trunk/lib-python/2.5.2/plat-irix5/flp.doc (props changed) pypy/trunk/lib-python/2.5.2/plat-irix5/readcd.doc (props changed) Log: Remove +x bit from DOC files. From getxsick at codespeak.net Thu Mar 11 22:45:16 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 22:45:16 +0100 (CET) Subject: [pypy-svn] r72143 - in pypy/trunk/lib-python/2.5.2: . bsddb Message-ID: <20100311214516.53B0A282BF1@codespeak.net> Author: getxsick Date: Thu Mar 11 22:45:14 2010 New Revision: 72143 Modified: pypy/trunk/lib-python/2.5.2/bsddb/dbshelve.py pypy/trunk/lib-python/2.5.2/cgi.py Log: Fix shebangs Modified: pypy/trunk/lib-python/2.5.2/bsddb/dbshelve.py ============================================================================== --- pypy/trunk/lib-python/2.5.2/bsddb/dbshelve.py (original) +++ pypy/trunk/lib-python/2.5.2/bsddb/dbshelve.py Thu Mar 11 22:45:14 2010 @@ -1,4 +1,4 @@ -#!/bin/env python +#!/usr/bin/env python #------------------------------------------------------------------------ # Copyright (c) 1997-2001 by Total Control Software # All Rights Reserved Modified: pypy/trunk/lib-python/2.5.2/cgi.py ============================================================================== --- pypy/trunk/lib-python/2.5.2/cgi.py (original) +++ pypy/trunk/lib-python/2.5.2/cgi.py Thu Mar 11 22:45:14 2010 @@ -1,4 +1,4 @@ -#! /usr/local/bin/python +#!/usr/bin/env python # NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is # intentionally NOT "/usr/bin/env python". On many systems From fijal at codespeak.net Thu Mar 11 22:45:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 11 Mar 2010 22:45:44 +0100 (CET) Subject: [pypy-svn] r72144 - pypy/trunk/pypy/interpreter Message-ID: <20100311214544.223E4282BF1@codespeak.net> Author: fijal Date: Thu Mar 11 22:45:42 2010 New Revision: 72144 Modified: pypy/trunk/pypy/interpreter/nestedscope.py Log: Remove getclosure, I don't think anyone is using it (grepping did not reveal) Simplify handling of cellvars - now it's a non-resizable list Modified: pypy/trunk/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/trunk/pypy/interpreter/nestedscope.py (original) +++ pypy/trunk/pypy/interpreter/nestedscope.py Thu Mar 11 22:45:42 2010 @@ -101,16 +101,12 @@ if len(closure) != nfreevars: raise ValueError("code object received a closure with " "an unexpected number of free variables") - self.cells = [Cell() for i in range(ncellvars)] - if closure: - self.cells += closure - - def getclosure(self): - if self.cells is None: - return None - ncellvars = len(self.pycode.co_cellvars) # not part of the closure - return self.cells[ncellvars:] - + self.cells = [None] * (ncellvars + nfreevars) + for i in range(ncellvars): + self.cells[i] = Cell() + for i in range(nfreevars): + self.cells[i + ncellvars] = closure[i] + def _getcells(self): return self.cells From getxsick at codespeak.net Thu Mar 11 23:55:58 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Thu, 11 Mar 2010 23:55:58 +0100 (CET) Subject: [pypy-svn] r72145 - pypy/build/ubuntu/debian Message-ID: <20100311225558.D75C7282BDC@codespeak.net> Author: getxsick Date: Thu Mar 11 23:55:57 2010 New Revision: 72145 Modified: pypy/build/ubuntu/debian/control Log: update desctiptions to Debian standards Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Thu Mar 11 23:55:57 2010 @@ -11,7 +11,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib (>= ${source:Version}), python, python-ctypes, gcc, libffi-dev, zlib1g-dev, libbz2-dev Recommends: pypy-doc, python-dev, libgc-dev, llvm-cfe, mono-gmcs, spidermonkey-bin, jasmin-sable, libreadline5-dev Suggests: gcl-dev -Description: PyPy-dev is a compiler writing toolchain. +Description: compiler writing toolchain This package provides the toolchain (including source code) for developing dynamic languages interpreters in RPython. It can be also used to compile PyPy's Python interpreter, although we suggest downloading it from trunk @@ -23,14 +23,14 @@ Package: pypy Architecture: i386 Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g -Description: PyPy is a python interpreter with Just in time compiler. - This package provides a binary version of the compiled interpreter, together - with several supported modules. +Description: python interpreter with Just in time compiler + This package provides a binary version of the compiled interpreter with + Just in time compilter, together with several supported modules. Package: pypy-doc Architecture: all Section: doc -Description: Documentation for PyPy +Description: documentation for PyPy This package provides documentation for the PyPy interpreter, the translation process, etc. You will definitely need it if you intend to play with PyPy, however all of those docs are online. @@ -44,9 +44,9 @@ Package: pypy-dotviewer Architecture: all -Depends: ${shlibs:Depends}, ${misc:Depends}, python-pygame, graphviz +Depends: ${shlibs:Depends}, ${misc:Depends}, python, python-pygame, graphviz Recommends: pypy | pypy-dev -Description: A viewer for dot files and graphs generated by PyPy +Description: viewer for dot files and graphs generated by PyPy This package provides a tool that can display .dot files in animated manner. It's widely used by various PyPy's debugging tools, like JIT assembler viewer, flowgraph viewer etc. From getxsick at codespeak.net Fri Mar 12 00:02:30 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 12 Mar 2010 00:02:30 +0100 (CET) Subject: [pypy-svn] r72146 - pypy/build/ubuntu/debian Message-ID: <20100311230230.1E61F282BDC@codespeak.net> Author: getxsick Date: Fri Mar 12 00:02:29 2010 New Revision: 72146 Modified: pypy/build/ubuntu/debian/rules Log: add more rules to keep perfection of the upstream Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Fri Mar 12 00:02:29 2010 @@ -55,8 +55,9 @@ rm -f debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o - rm -f debian/pypy-lib/usr/share/pypy-1.2/lib-python/2.5.2/idlelib/idle.bat rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ + chmod a-x debian/pypy-lib/usr/share/pypy-1.2/lib-python/2.5.2/idlelib/idle.bat + chmod a-x debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/cli/src/pypylib.dll install-arch: dh_testdir From getxsick at codespeak.net Fri Mar 12 00:24:11 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 12 Mar 2010 00:24:11 +0100 (CET) Subject: [pypy-svn] r72147 - pypy/build/ubuntu/debian Message-ID: <20100311232411.1D704282BE4@codespeak.net> Author: getxsick Date: Fri Mar 12 00:24:09 2010 New Revision: 72147 Modified: pypy/build/ubuntu/debian/control Log: update descriptin Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 12 00:24:09 2010 @@ -14,7 +14,7 @@ Description: compiler writing toolchain This package provides the toolchain (including source code) for developing dynamic languages interpreters in RPython. It can be also used to compile - PyPy's Python interpreter, although we suggest downloading it from trunk + PyPy's Python interpreter, although it is suggested to download it from trunk in this case. . Install this package if you want to translate RPython programs, or to From fijal at codespeak.net Fri Mar 12 02:04:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 02:04:11 +0100 (CET) Subject: [pypy-svn] r72148 - in pypy/trunk/pypy/jit/tool: . test Message-ID: <20100312010411.7FE27282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 02:04:10 2010 New Revision: 72148 Added: pypy/trunk/pypy/jit/tool/test/test_traceviewer.py - copied, changed from r72128, pypy/trunk/pypy/jit/tool/test/test_otherviewer.py pypy/trunk/pypy/jit/tool/traceviewer.py - copied, changed from r72141, pypy/trunk/pypy/jit/tool/otherviewer.py Removed: pypy/trunk/pypy/jit/tool/otherviewer.py pypy/trunk/pypy/jit/tool/test/test_otherviewer.py Log: Rename otherviewer->traceviewer Copied: pypy/trunk/pypy/jit/tool/test/test_traceviewer.py (from r72128, pypy/trunk/pypy/jit/tool/test/test_otherviewer.py) ============================================================================== --- pypy/trunk/pypy/jit/tool/test/test_otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/test/test_traceviewer.py Fri Mar 12 02:04:10 2010 @@ -1,6 +1,6 @@ import math import py -from pypy.jit.tool.otherviewer import splitloops, FinalBlock, Block,\ +from pypy.jit.tool.traceviewer import splitloops, FinalBlock, Block,\ split_one_loop, postprocess, main, get_gradient_color Copied: pypy/trunk/pypy/jit/tool/traceviewer.py (from r72141, pypy/trunk/pypy/jit/tool/otherviewer.py) ============================================================================== --- pypy/trunk/pypy/jit/tool/otherviewer.py (original) +++ pypy/trunk/pypy/jit/tool/traceviewer.py Fri Mar 12 02:04:10 2010 @@ -16,7 +16,23 @@ class SubPage(GraphPage): def compute(self, graph): dotgen = DotGen(str(graph.no)) - dotgen.emit_node(graph.name(), shape="box", label=graph.content) + # split over debug_merge_points + counter = 0 + lines = graph.content.split("\n") + lines_so_far = [] + for line in lines: + line = re.sub('.\[.*\]', '', line) + if 'debug_merge_point' in line: + dotgen.emit_node('node%d' % counter, shape="box", + label="\n".join(lines_so_far)) + if counter != 0: + dotgen.emit_edge('node%d' % (counter - 1), 'node%d' % counter) + counter += 1 + lines_so_far = [] + lines_so_far.append(line) + dotgen.emit_node('node%d' % counter, shape="box", + label="\n".join(lines_so_far)) + dotgen.emit_edge('node%d' % (counter - 1), 'node%d' % counter) self.source = dotgen.generate(target=None) class Page(GraphPage): @@ -225,12 +241,7 @@ else: loop.ratio = float(opsno) / bcodes content = loop.content - lines = content.split("\n") - if len(lines) > LINE_CUTOFF: - lines = lines[:LINE_CUTOFF] + ["%d more lines..." % (len(lines) - LINE_CUTOFF)] - for i, line in enumerate(lines): - lines[i] = re.sub("\[.*\]", "", line) - loop.content = "Logfile at %d\n" % loop.startlineno + "\n".join(lines) + loop.content = "Logfile at %d\n" % loop.startlineno + content loop.postprocess(loops, memo) def postprocess(loops, allloops): From benjamin at codespeak.net Fri Mar 12 02:07:49 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 12 Mar 2010 02:07:49 +0100 (CET) Subject: [pypy-svn] r72149 - pypy/trunk/pypy/jit/tool Message-ID: <20100312010749.EDDE7282BE4@codespeak.net> Author: benjamin Date: Fri Mar 12 02:07:48 2010 New Revision: 72149 Modified: pypy/trunk/pypy/jit/tool/traceviewer.py Log: fix comment Modified: pypy/trunk/pypy/jit/tool/traceviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/traceviewer.py (original) +++ pypy/trunk/pypy/jit/tool/traceviewer.py Fri Mar 12 02:07:48 2010 @@ -1,5 +1,5 @@ #!/usr/bin/env python -""" Usage: otherviewer.py loopfile +""" Usage: traceviewer.py loopfile """ import optparse From fijal at codespeak.net Fri Mar 12 02:15:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 02:15:05 +0100 (CET) Subject: [pypy-svn] r72150 - pypy/trunk/pypy/jit/tool Message-ID: <20100312011505.69947282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 02:15:04 2010 New Revision: 72150 Modified: pypy/trunk/pypy/jit/tool/traceviewer.py Log: Kill some code. Kills dict-dependency order as a side effect (code was not doing anything useful anyway) Modified: pypy/trunk/pypy/jit/tool/traceviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/traceviewer.py (original) +++ pypy/trunk/pypy/jit/tool/traceviewer.py Fri Mar 12 02:15:04 2010 @@ -38,9 +38,7 @@ class Page(GraphPage): def compute(self, graphs): dotgen = DotGen('trace') - self.loops = set() - for graph in graphs: - graph.grab_loops(self.loops) + self.loops = graphs self.links = {} self.cache = {} for loop in self.loops: @@ -114,13 +112,6 @@ def postprocess(self, loops, memo): postprocess_loop(self.target, loops, memo) - def grab_loops(self, loops): - if self in loops: - return - loops.add(self) - if self.target is not None: - self.target.grab_loops(loops) - def generate(self, dotgen): BasicBlock.generate(self, dotgen) if self.target is not None: @@ -136,13 +127,6 @@ postprocess_loop(self.left, loops, memo) postprocess_loop(self.right, loops, memo) - def grab_loops(self, loops): - if self in loops: - return - loops.add(self) - self.left.grab_loops(loops) - self.right.grab_loops(loops) - def generate(self, dotgen): BasicBlock.generate(self, dotgen) dotgen.emit_edge(self.name(), self.left.name()) From fijal at codespeak.net Fri Mar 12 02:42:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 02:42:17 +0100 (CET) Subject: [pypy-svn] r72151 - pypy/trunk/pypy/jit/tool Message-ID: <20100312014217.CE0E6282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 02:42:16 2010 New Revision: 72151 Modified: pypy/trunk/pypy/jit/tool/traceviewer.py Log: Make boxes linkable. This makes it easier to trace stuff Modified: pypy/trunk/pypy/jit/tool/traceviewer.py ============================================================================== --- pypy/trunk/pypy/jit/tool/traceviewer.py (original) +++ pypy/trunk/pypy/jit/tool/traceviewer.py Fri Mar 12 02:42:16 2010 @@ -15,6 +15,7 @@ class SubPage(GraphPage): def compute(self, graph): + self.links = {} dotgen = DotGen(str(graph.no)) # split over debug_merge_points counter = 0 @@ -22,6 +23,9 @@ lines_so_far = [] for line in lines: line = re.sub('.\[.*\]', '', line) + boxes = re.findall('([pif]\d+)', line) + for box in boxes: + self.links[box] = box if 'debug_merge_point' in line: dotgen.emit_node('node%d' % counter, shape="box", label="\n".join(lines_so_far)) From arigo at codespeak.net Fri Mar 12 03:01:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 03:01:44 +0100 (CET) Subject: [pypy-svn] r72152 - in pypy/release/1.2.x: lib-python/2.5.2 lib-python/2.5.2/bsddb lib-python/2.5.2/lib-tk lib-python/2.5.2/plat-atheos lib-python/2.5.2/plat-freebsd4 lib-python/2.5.2/plat-freebsd5 lib-python/2.5.2/plat-freebsd6 lib-python/2.5.2/plat-freebsd7 lib-python/2.5.2/plat-irix5 lib-python/2.5.2/plat-mac/Carbon lib-python/2.5.2/plat-os2emx lib-python/2.5.2/plat-sunos5 lib-python/2.5.2/test pypy/lib/app_test pypy/lib/test2 pypy/translator/microbench/pybench Message-ID: <20100312020144.0D6A7282BE4@codespeak.net> Author: arigo Date: Fri Mar 12 03:01:41 2010 New Revision: 72152 Modified: pypy/release/1.2.x/lib-python/2.5.2/bsddb/dbshelve.py pypy/release/1.2.x/lib-python/2.5.2/cgi.py pypy/release/1.2.x/lib-python/2.5.2/lib-tk/Tix.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-atheos/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-freebsd4/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-freebsd5/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-freebsd6/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-freebsd7/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/AL.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/CD.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/CL.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/CL_old.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/DEVICE.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/ERRNO.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/FILE.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/FL.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/GET.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/GL.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/GLWS.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/IN.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/IOCTL.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/SV.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/WAIT.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/cddb.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/cdplayer.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/flp.doc (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/flp.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/jpeg.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/panel.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/panelparser.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/readcd.doc (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/readcd.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-irix5/torgb.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-mac/Carbon/CG.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-mac/Carbon/CarbonEvents.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-mac/Carbon/CarbonEvt.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-mac/Carbon/CoreGraphics.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-os2emx/regen (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-sunos5/IN.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/plat-sunos5/SUNAUDIODEV.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/runpy.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/test/test_aepack.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/test/test_binascii.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/test/test_grp.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/test/test_htmlparser.py (props changed) pypy/release/1.2.x/lib-python/2.5.2/test/test_wsgiref.py (props changed) pypy/release/1.2.x/pypy/lib/app_test/test_binascii.py (props changed) pypy/release/1.2.x/pypy/lib/test2/pickledtasklet.py pypy/release/1.2.x/pypy/translator/microbench/pybench/platform.py pypy/release/1.2.x/pypy/translator/microbench/pybench/pybench.py Log: Updates to the #! lines and the svn:executable property: svn merge -r71717:71719 svn+ssh://codespeak.net/svn/pypy/trunk svn merge -r71768:71769 svn+ssh://codespeak.net/svn/pypy/trunk svn merge -r71958:71959 svn+ssh://codespeak.net/svn/pypy/trunk svn merge -r72141:72143 svn+ssh://codespeak.net/svn/pypy/trunk Modified: pypy/release/1.2.x/lib-python/2.5.2/bsddb/dbshelve.py ============================================================================== --- pypy/release/1.2.x/lib-python/2.5.2/bsddb/dbshelve.py (original) +++ pypy/release/1.2.x/lib-python/2.5.2/bsddb/dbshelve.py Fri Mar 12 03:01:41 2010 @@ -1,4 +1,4 @@ -#!/bin/env python +#!/usr/bin/env python #------------------------------------------------------------------------ # Copyright (c) 1997-2001 by Total Control Software # All Rights Reserved Modified: pypy/release/1.2.x/lib-python/2.5.2/cgi.py ============================================================================== --- pypy/release/1.2.x/lib-python/2.5.2/cgi.py (original) +++ pypy/release/1.2.x/lib-python/2.5.2/cgi.py Fri Mar 12 03:01:41 2010 @@ -1,4 +1,4 @@ -#! /usr/local/bin/python +#!/usr/bin/env python # NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is # intentionally NOT "/usr/bin/env python". On many systems Modified: pypy/release/1.2.x/pypy/lib/test2/pickledtasklet.py ============================================================================== --- pypy/release/1.2.x/pypy/lib/test2/pickledtasklet.py (original) +++ pypy/release/1.2.x/pypy/lib/test2/pickledtasklet.py Fri Mar 12 03:01:41 2010 @@ -1,3 +1,4 @@ +#!/usr/bin/env python import pickle, sys import stackless Modified: pypy/release/1.2.x/pypy/translator/microbench/pybench/platform.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/microbench/pybench/platform.py (original) +++ pypy/release/1.2.x/pypy/translator/microbench/pybench/platform.py Fri Mar 12 03:01:41 2010 @@ -1,4 +1,4 @@ -#!/usr/local/bin/python +#!/usr/bin/env python """ This module tries to retrieve as much platform identifying data as possible. It makes this information available via function APIs. Modified: pypy/release/1.2.x/pypy/translator/microbench/pybench/pybench.py ============================================================================== --- pypy/release/1.2.x/pypy/translator/microbench/pybench/pybench.py (original) +++ pypy/release/1.2.x/pypy/translator/microbench/pybench/pybench.py Fri Mar 12 03:01:41 2010 @@ -1,4 +1,4 @@ -#!/usr/local/bin/python -O +#!/usr/bin/env python -O """ A Python Benchmark Suite """ From fijal at codespeak.net Fri Mar 12 03:14:19 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 03:14:19 +0100 (CET) Subject: [pypy-svn] r72153 - pypy/trunk/pypy/module/pypyjit Message-ID: <20100312021419.D13F2282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 03:14:18 2010 New Revision: 72153 Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py Log: I *think* it's correct to clean up last_exception here (there is nothing that can happen between now and cleaning up of last_exception in PyFrame.execute_frame). Should help when we exit the frame from the JIT and we have 'entry_bridge' going to DoneWithThisFrameDescrRef Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Fri Mar 12 03:14:18 2010 @@ -76,6 +76,7 @@ self.valuestackdepth = hint(self.valuestackdepth, promote=True) next_instr = self.handle_bytecode(co_code, next_instr, ec) except ExitFrame: + self.last_exception = None return self.popvalue() def JUMP_ABSOLUTE(f, jumpto, _, ec=None): From fijal at codespeak.net Fri Mar 12 03:38:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 03:38:34 +0100 (CET) Subject: [pypy-svn] r72154 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100312023834.1574D282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 03:38:32 2010 New Revision: 72154 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: Add a test that I thought would work, not sure why it does not Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Mar 12 03:38:32 2010 @@ -572,6 +572,21 @@ # we allocate virtual ref and frame, we don't want block assert len(bytecode.get_opnames('new_with_vtable')) == 2 + def test_import_in_function(self): + py.test.skip("does not work, why???") + self.run_source(''' + def main(): + i = 0 + while i < 100: + from sys import version + i += 1 + return i + ''', 100, ([], 100)) + bytecode, = self.get_by_bytecode('IMPORT_NAME') + bytecode2, = self.get_by_bytecode('IMPORT_FROM') + assert len(bytecode.get_opnames('call')) == 0 + assert len(bytecode2.get_opnames('call')) == 0 + class AppTestJIT(PyPyCJITTests): def setup_class(cls): if not option.runappdirect: From fijal at codespeak.net Fri Mar 12 03:41:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 03:41:59 +0100 (CET) Subject: [pypy-svn] r72155 - pypy/extradoc/planning Message-ID: <20100312024159.C4B6B282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 03:41:58 2010 New Revision: 72155 Modified: pypy/extradoc/planning/jit.txt Log: add a hard task Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Fri Mar 12 03:41:58 2010 @@ -43,6 +43,11 @@ this case and some other cases, the static refcount can only be 1, so we can optimize away the copy. +- a suggestion - if we call some code via call_assembler that raises an + exception, in theory we could do something smarter in case our frames + don't escape and call simplified version that does not allocate all + frames. Sounds hard + Python interpreter: - goal: on average <=5 guards per original bytecode. From fijal at codespeak.net Fri Mar 12 03:54:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 03:54:25 +0100 (CET) Subject: [pypy-svn] r72156 - pypy/extradoc/planning Message-ID: <20100312025425.04FEE282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 03:54:24 2010 New Revision: 72156 Modified: pypy/extradoc/planning/jit.txt Log: another issue Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Fri Mar 12 03:54:24 2010 @@ -48,6 +48,17 @@ don't escape and call simplified version that does not allocate all frames. Sounds hard +- if we move a promotion up the chain, some arguments don't get replaced + with constants (those between current and previous locations). So we get + like + + guard_value(p3, ConstPtr(X)) + getfield_gc(p3, descr) + getfield_gc(ConstPtr(X), descr) + + maybe we should move promote even higher, before the first use and we + could possibly remove more stuff? + Python interpreter: - goal: on average <=5 guards per original bytecode. From fijal at codespeak.net Fri Mar 12 04:00:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 04:00:40 +0100 (CET) Subject: [pypy-svn] r72157 - in pypy/trunk/pypy/module/pypyjit: . test Message-ID: <20100312030040.8DEE1282BE4@codespeak.net> Author: fijal Date: Fri Mar 12 04:00:39 2010 New Revision: 72157 Modified: pypy/trunk/pypy/module/pypyjit/policy.py pypy/trunk/pypy/module/pypyjit/test/test_policy.py Log: Not sure what this test means. I'll tentatively delete it (I want to look at getdictvalue there). Modified: pypy/trunk/pypy/module/pypyjit/policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/policy.py Fri Mar 12 04:00:39 2010 @@ -8,12 +8,10 @@ modname == '__builtin__.interp_classobj' or modname == '__builtin__.functional'): return True - if modname == 'sys.state': - return True if '.' in modname: modname, _ = modname.split('.', 1) if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions', - 'imp']: + 'imp', 'sys']: return True return False Modified: pypy/trunk/pypy/module/pypyjit/test/test_policy.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_policy.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_policy.py Fri Mar 12 04:00:39 2010 @@ -39,7 +39,3 @@ def test_see_jit_module(): assert pypypolicy.look_inside_pypy_module('pypyjit.interp_jit') -def test_module_with_stuff_in_init(): - from pypy.module.sys import Module - assert not pypypolicy.look_inside_function(Module.getdictvalue.im_func) - From fijal at codespeak.net Fri Mar 12 05:54:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 05:54:56 +0100 (CET) Subject: [pypy-svn] r72158 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100312045456.35129282BEC@codespeak.net> Author: fijal Date: Fri Mar 12 05:54:53 2010 New Revision: 72158 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: This test now passes Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Fri Mar 12 05:54:53 2010 @@ -573,7 +573,6 @@ assert len(bytecode.get_opnames('new_with_vtable')) == 2 def test_import_in_function(self): - py.test.skip("does not work, why???") self.run_source(''' def main(): i = 0 @@ -584,7 +583,7 @@ ''', 100, ([], 100)) bytecode, = self.get_by_bytecode('IMPORT_NAME') bytecode2, = self.get_by_bytecode('IMPORT_FROM') - assert len(bytecode.get_opnames('call')) == 0 + assert len(bytecode.get_opnames('call')) == 2 # split_chr and list_pop assert len(bytecode2.get_opnames('call')) == 0 class AppTestJIT(PyPyCJITTests): From fijal at codespeak.net Fri Mar 12 18:10:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:10:26 +0100 (CET) Subject: [pypy-svn] r72159 - pypy/extradoc/planning Message-ID: <20100312171026.6C70551054@codespeak.net> Author: fijal Date: Fri Mar 12 18:10:24 2010 New Revision: 72159 Modified: pypy/extradoc/planning/jit.txt Log: Write down a possible solution Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Fri Mar 12 18:10:24 2010 @@ -43,6 +43,10 @@ this case and some other cases, the static refcount can only be 1, so we can optimize away the copy. + I think enough would be to make jit aware of ll_arraycopy, so it knows + a copy of a virtual array yields another virtual array and will optimize + everything away on it's own. + - a suggestion - if we call some code via call_assembler that raises an exception, in theory we could do something smarter in case our frames don't escape and call simplified version that does not allocate all From fijal at codespeak.net Fri Mar 12 18:11:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:11:33 +0100 (CET) Subject: [pypy-svn] r72160 - pypy/trunk/pypy/module/pypyjit Message-ID: <20100312171133.6D1C051054@codespeak.net> Author: fijal Date: Fri Mar 12 18:11:32 2010 New Revision: 72160 Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py Log: revert that change - didn't help anything Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Fri Mar 12 18:11:32 2010 @@ -76,7 +76,6 @@ self.valuestackdepth = hint(self.valuestackdepth, promote=True) next_instr = self.handle_bytecode(co_code, next_instr, ec) except ExitFrame: - self.last_exception = None return self.popvalue() def JUMP_ABSOLUTE(f, jumpto, _, ec=None): From arigo at codespeak.net Fri Mar 12 18:12:01 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 18:12:01 +0100 (CET) Subject: [pypy-svn] r72161 - pypy/extradoc/pypy.org/source Message-ID: <20100312171201.F341951054@codespeak.net> Author: arigo Date: Fri Mar 12 18:12:00 2010 New Revision: 72161 Modified: pypy/extradoc/pypy.org/source/download.txt Log: Remove the win32-sandbox, which does not work for now. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Fri Mar 12 18:12:00 2010 @@ -96,11 +96,9 @@ * `Linux binary`__ * `Mac OS/X binary`__ -* `Windows binary`__ .. __: http://pypy.org/download/pypy-1.2-linux-sandbox.bz2 .. __: http://pypy.org/download/pypy-1.2-osx-sandbox.bz2 -.. __: http://pypy.org/download/pypy-1.2-win32-sandbox.zip It is also possible to translate_ a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively @@ -109,8 +107,8 @@ If your CPU is a 64-bit machine and you want to translate_ a 32-bit version of PyPy yourself, `here are hints`_. -The native 64-bit version needs testing and careful reviewing; -`contact us`_! +The Windows and the native 64-bit versions both need testing and careful +reviewing; `contact us`_! .. _`Stackless version`: From fijal at codespeak.net Fri Mar 12 18:12:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:12:22 +0100 (CET) Subject: [pypy-svn] r72162 - pypy/extradoc/planning/1.2 Message-ID: <20100312171222.4CC4D282BEC@codespeak.net> Author: fijal Date: Fri Mar 12 18:12:21 2010 New Revision: 72162 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: I think we should be more epxlicit here Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:12:21 2010 @@ -4,8 +4,10 @@ We are pleased to announce PyPy's 1.2 release. This version 1.2 is a major milestone and it is -the first release to ship a `Just in time compiler`_ that is known to speed -up some real-world Python programs. The main theme for the 1.2 release is +the first release to ship a `Just in time compiler`_ that is known to be faster +than CPython (and unladen swallow) on some real-world applications (or the best +benchmarks we could get for them). +The main theme for the 1.2 release is **speed**. The JIT is stable and we don't observe crashes. From fijal at codespeak.net Fri Mar 12 18:14:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:14:08 +0100 (CET) Subject: [pypy-svn] r72163 - pypy/extradoc/planning/1.2 Message-ID: <20100312171408.09435282BEC@codespeak.net> Author: fijal Date: Fri Mar 12 18:14:07 2010 New Revision: 72163 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: strike down PPA as they're not ready Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:14:07 2010 @@ -28,8 +28,6 @@ * Introducing `speed.pypy.org`_, a new service that monitors our performance nightly. -* Introducing Ubuntu packages on `PPA`_, done by `Bartosz Skowron`_. - Known JIT problems (or why you should consider this beta software) are: * The only supported platform is 32bit x86 for now, we're looking for help with From arigo at codespeak.net Fri Mar 12 18:19:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 18:19:52 +0100 (CET) Subject: [pypy-svn] r72164 - pypy/release/1.2.0 Message-ID: <20100312171952.B12B8282BEF@codespeak.net> Author: arigo Date: Fri Mar 12 18:19:51 2010 New Revision: 72164 Added: pypy/release/1.2.0/ - copied from r72163, pypy/release/1.2.x/ Log: Make the release tag. From fijal at codespeak.net Fri Mar 12 18:22:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:22:15 +0100 (CET) Subject: [pypy-svn] r72167 - pypy/extradoc/planning/1.2 Message-ID: <20100312172215.7B2E6282BEF@codespeak.net> Author: fijal Date: Fri Mar 12 18:22:14 2010 New Revision: 72167 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: Linkify and prettify announcement Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:22:14 2010 @@ -3,17 +3,14 @@ ============================ We are pleased to announce PyPy's 1.2 release. -This version 1.2 is a major milestone and it is -the first release to ship a `Just in time compiler`_ that is known to be faster -than CPython (and unladen swallow) on some real-world applications (or the best -benchmarks we could get for them). -The main theme for the 1.2 release is -**speed**. - -The JIT is stable and we don't observe crashes. -Nevertheless we would recommend you to -treat it as beta software and as a way to try the JIT out to see how it -works for you. +This version 1.2 is a major milestone and it is the first release to ship +a `Just in time compiler`_ that is known to be faster than CPython +(and unladen swallow) on some real-world applications (or the best benchmarks +we could get for them). The main theme for the 1.2 release is **speed**. + +The JIT is stable and we don't observe crashes. Nevertheless we would +recommend you to treat it as beta software and as a way to try the JIT out +to see how it works for you. Highlights: @@ -28,6 +25,9 @@ * Introducing `speed.pypy.org`_, a new service that monitors our performance nightly. +* There will be ubuntu packages on `PyPy's PPA`_ made by Bartosz Skowron, + however various troubles prevented us from having them as of now. + Known JIT problems (or why you should consider this beta software) are: * The only supported platform is 32bit x86 for now, we're looking for help with @@ -43,4 +43,15 @@ your platform is not supported, you can `try building from the source`_. PyPy release team, -XXX folks +Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc + +.. _`Just in time compiler`: http://en.wikipedia.org/wiki/Just-in-time_compilation +.. _`new PyPy website`: http://pypy.org +.. _`various`: http://morepypy.blogspot.com/2010/03/hello.html +.. _`blog`: http://morepypy.blogspot.com/2010/01/nightly-graphs-of-pypys-performance.html +.. _`posts`: http://morepypy.blogspot.com/2009/11/some-benchmarking.html +.. _`tav`: http://tav.espians.com/ +.. _`download page`: http://pypy.org/download.html +.. _`try building from the source`: http://pypy.org/download.html#building-from-source +.. _`PyPy's PPA`: https://launchpad.net/~pypy/+archive/ppa +.. _`speed.pypy.org`: http://speed.pypy.org From fijal at codespeak.net Fri Mar 12 18:22:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:22:49 +0100 (CET) Subject: [pypy-svn] r72168 - pypy/extradoc/planning/1.2 Message-ID: <20100312172249.2559F282BEF@codespeak.net> Author: fijal Date: Fri Mar 12 18:22:47 2010 New Revision: 72168 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: mention pypy.org explicitely Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:22:47 2010 @@ -19,8 +19,8 @@ * Various interpreter optimizations that improve performance as well as help save memory. Read our `various`_ `blog`_ `posts`_ about achievements. -* Introducing a `new PyPy website`_ made by `tav`_ and improved by the PyPy - team. +* Introducing a `new PyPy website`_ at pypy.org made by `tav`_ and improved + by the PyPy team. * Introducing `speed.pypy.org`_, a new service that monitors our performance nightly. From fijal at codespeak.net Fri Mar 12 18:29:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:29:34 +0100 (CET) Subject: [pypy-svn] r72169 - pypy/extradoc/planning/1.2 Message-ID: <20100312172934.B069B5105A@codespeak.net> Author: fijal Date: Fri Mar 12 18:29:33 2010 New Revision: 72169 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: add a link Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:29:33 2010 @@ -2,7 +2,7 @@ Introducing PyPy 1.2 release ============================ -We are pleased to announce PyPy's 1.2 release. +We are pleased to announce `PyPy's 1.2 release`_. This version 1.2 is a major milestone and it is the first release to ship a `Just in time compiler`_ that is known to be faster than CPython (and unladen swallow) on some real-world applications (or the best benchmarks @@ -45,6 +45,7 @@ PyPy release team, Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc +.. _`PyPy's 1.2 release`: http://pypy.org/ .. _`Just in time compiler`: http://en.wikipedia.org/wiki/Just-in-time_compilation .. _`new PyPy website`: http://pypy.org .. _`various`: http://morepypy.blogspot.com/2010/03/hello.html From arigo at codespeak.net Fri Mar 12 18:36:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 18:36:32 +0100 (CET) Subject: [pypy-svn] r72170 - pypy/extradoc/planning/1.2 Message-ID: <20100312173632.22E4551056@codespeak.net> Author: arigo Date: Fri Mar 12 18:36:30 2010 New Revision: 72170 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: Minor enhancements. Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:36:30 2010 @@ -4,12 +4,12 @@ We are pleased to announce `PyPy's 1.2 release`_. This version 1.2 is a major milestone and it is the first release to ship -a `Just in time compiler`_ that is known to be faster than CPython +a **Just-in-Time compiler** that is known to be faster than CPython (and unladen swallow) on some real-world applications (or the best benchmarks we could get for them). The main theme for the 1.2 release is **speed**. The JIT is stable and we don't observe crashes. Nevertheless we would -recommend you to treat it as beta software and as a way to try the JIT out +recommend you to treat it as beta software and as a way to try out the JIT to see how it works for you. Highlights: @@ -37,17 +37,16 @@ the assembler can consume; it is thus possible (although unlikely) that the assembler ends up using unreasonable amounts of memory. -If you want to try PyPy, go to `download page`_ on our excellent new site +If you want to try PyPy, go to the `download page`_ on our excellent new site and find the binary for your platform. If the binary does not work (e.g. on Linux, because of different versions of external .so dependencies), or if your platform is not supported, you can `try building from the source`_. -PyPy release team, +The PyPy release team (working of course for the full PyPy team), Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc .. _`PyPy's 1.2 release`: http://pypy.org/ -.. _`Just in time compiler`: http://en.wikipedia.org/wiki/Just-in-time_compilation -.. _`new PyPy website`: http://pypy.org +.. _`new PyPy website`: http://pypy.org/ .. _`various`: http://morepypy.blogspot.com/2010/03/hello.html .. _`blog`: http://morepypy.blogspot.com/2010/01/nightly-graphs-of-pypys-performance.html .. _`posts`: http://morepypy.blogspot.com/2009/11/some-benchmarking.html From fijal at codespeak.net Fri Mar 12 18:38:41 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:38:41 +0100 (CET) Subject: [pypy-svn] r72171 - pypy/extradoc/pypy.org Message-ID: <20100312173841.8DEF551056@codespeak.net> Author: fijal Date: Fri Mar 12 18:38:40 2010 New Revision: 72171 Modified: pypy/extradoc/pypy.org/download.html Log: update html Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Fri Mar 12 18:38:40 2010 @@ -111,17 +111,16 @@

        It is also possible to translate a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively complicated, this reduce a bit the level of confidence we can put in it.

        If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

        -

        The native 64-bit version needs testing and careful reviewing; -contact us!

        +

        The Windows and the native 64-bit versions both need testing and careful +reviewing; contact us!

    -
    +

    “Stackless” version

    Provides Stackless extensions, as well as greenlets. These binaries work on 32-bit x86 (IA-32) CPUs as well as x86-64 CPUs @@ -140,9 +139,9 @@

    Installing

    All versions are packaged in a tar.bz2 or zip file. When uncompressed, they run in-place. On Linux or Mac OS/X, they can also be -installed by manually moving the files in the following directories:

    +installed by manually moving the files:

    -/usr/bin/pypy
    +/usr/bin/pypy     # or pypy-nojit etc.
     /usr/share/pypy-1.2/lib-python/*
     /usr/share/pypy-1.2/pypy/*
     
    From fijal at codespeak.net Fri Mar 12 18:43:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:43:55 +0100 (CET) Subject: [pypy-svn] r72172 - pypy/extradoc/pypy.org/css Message-ID: <20100312174355.19748282BF1@codespeak.net> Author: fijal Date: Fri Mar 12 18:43:53 2010 New Revision: 72172 Modified: pypy/extradoc/pypy.org/css/site.css Log: kill inconsolata-2, it looks obscure Modified: pypy/extradoc/pypy.org/css/site.css ============================================================================== --- pypy/extradoc/pypy.org/css/site.css (original) +++ pypy/extradoc/pypy.org/css/site.css Fri Mar 12 18:43:53 2010 @@ -248,7 +248,7 @@ #main pre { font-size: 14px; - font-family: "inconsolata-1", "inconsolata-2", Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; + font-family: "inconsolata-1", Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; } #main ul, #main ol { From arigo at codespeak.net Fri Mar 12 18:45:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 18:45:37 +0100 (CET) Subject: [pypy-svn] r72173 - pypy/extradoc/pypy.org/source Message-ID: <20100312174537.74B72282BF0@codespeak.net> Author: arigo Date: Fri Mar 12 18:45:35 2010 New Revision: 72173 Modified: pypy/extradoc/pypy.org/source/compat.txt pypy/extradoc/pypy.org/source/download.txt pypy/extradoc/pypy.org/source/features.txt Log: Minor rephrasings. Modified: pypy/extradoc/pypy.org/source/compat.txt ============================================================================== --- pypy/extradoc/pypy.org/source/compat.txt (original) +++ pypy/extradoc/pypy.org/source/compat.txt Fri Mar 12 18:45:35 2010 @@ -3,12 +3,12 @@ title: Python compatibility --- -PyPy implements Python language version 2.5. It supports all of the core +PyPy implements the Python language version 2.5. It supports all of the core language, passing Python test suite (with minor modifications that were -already accepted in main python in newer versions). It supports most -of commonly used Python `standard library modules`_, list below. +already accepted in the main python in newer versions). It supports most +of the commonly used Python `standard library modules`_; details below. -PyPy does not support `CPython C API`_, which means that third party +PyPy does not support the `CPython C API`_, which means that third party libraries for python, written in C, will not work. Standard library modules supported by PyPy, in alphabetical order: @@ -37,9 +37,9 @@ Known differencies that are not going to be fixed: -* PyPy does not support refcounting semantics. The code below +* PyPy does not support refcounting semantics. The following code won't fill the file immediately, but only after a certain period - of time, when the GC will collect + of time, when the GC does a collection: .. syntax:: python @@ -63,8 +63,8 @@ * We don't support certain attributes that were decided to be implementation-dependent. For example, ``gc.get_referrers`` does not exist. Others may have different behavior; for example, ``gc.enable`` and - ``gc.disable`` are supported, but they don't enable and disable GC, but - instead enable and disable running of finalizers. + ``gc.disable`` are supported, but they don't enable and disable the GC, but + instead just enable and disable the running of finalizers. * You can't attach a ``__del__`` method to a class after its creation. Modified: pypy/extradoc/pypy.org/source/download.txt ============================================================================== --- pypy/extradoc/pypy.org/source/download.txt (original) +++ pypy/extradoc/pypy.org/source/download.txt Fri Mar 12 18:45:35 2010 @@ -7,10 +7,11 @@ ============================================================ Here are the various binaries of **PyPy 1.2** that we provide for x86 Linux, -Mac OS/X or Windows. This is the first release of PyPy containing JIT, hence +Mac OS/X or Windows. This is the first release of PyPy containing +a JIT compiler, hence the main goal is to try this out and see how it works for you. We put -a lot of effort into making JIT a stable piece of software and we don't -observe crashes, however, please consider it a beta version to try things out. +a lot of effort into making the JIT a stable piece of software and we don't +observe crashes; however, please consider it a beta version to try things out. .. class:: download_menu @@ -102,7 +103,8 @@ It is also possible to translate_ a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively -complicated, this reduce a bit the level of confidence we can put in it. +complicated, this reduce a bit the level of confidence we can put in +the result. If your CPU is a 64-bit machine and you want to translate_ a 32-bit version of PyPy yourself, `here are hints`_. Modified: pypy/extradoc/pypy.org/source/features.txt ============================================================================== --- pypy/extradoc/pypy.org/source/features.txt (original) +++ pypy/extradoc/pypy.org/source/features.txt Fri Mar 12 18:45:35 2010 @@ -7,9 +7,9 @@ =========================================================== **PyPy 1.2** implements **Python 2.5.** It supports all of the core -language, passing Python test suite (with minor modifications that were -already accepted in main python in newer versions). It supports most -of commonly used Python standard library modules. For known differences +language, passing the Python test suite (with minor modifications that were +already accepted in the main python in newer versions). It supports most +of the commonly used Python standard library modules. For known differences with CPython, see our `compatibility`_ page. If you are interested in helping with 2.6, 2.7 or 3.x features, `contact us`_! From fijal at codespeak.net Fri Mar 12 18:46:45 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:46:45 +0100 (CET) Subject: [pypy-svn] r72174 - pypy/extradoc/pypy.org/css Message-ID: <20100312174645.39370282BEE@codespeak.net> Author: fijal Date: Fri Mar 12 18:46:43 2010 New Revision: 72174 Modified: pypy/extradoc/pypy.org/css/site.css Log: increase font size by one. Small is nice, but causes windows rendering problems Modified: pypy/extradoc/pypy.org/css/site.css ============================================================================== --- pypy/extradoc/pypy.org/css/site.css (original) +++ pypy/extradoc/pypy.org/css/site.css Fri Mar 12 18:46:43 2010 @@ -247,8 +247,8 @@ } #main pre { - font-size: 14px; - font-family: "inconsolata-1", Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; + font-size: 15px; + font-family: "inconsolata-2", "inconsolata-1", Monaco, "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace; } #main ul, #main ol { From fijal at codespeak.net Fri Mar 12 18:47:45 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 18:47:45 +0100 (CET) Subject: [pypy-svn] r72175 - pypy/extradoc/pypy.org Message-ID: <20100312174745.EEEAB282BEE@codespeak.net> Author: fijal Date: Fri Mar 12 18:47:44 2010 New Revision: 72175 Modified: pypy/extradoc/pypy.org/compat.html pypy/extradoc/pypy.org/download.html pypy/extradoc/pypy.org/features.html Log: Update html Modified: pypy/extradoc/pypy.org/compat.html ============================================================================== --- pypy/extradoc/pypy.org/compat.html (original) +++ pypy/extradoc/pypy.org/compat.html Fri Mar 12 18:47:44 2010 @@ -47,11 +47,11 @@

    Python compatibility

    -

    PyPy implements Python language version 2.5. It supports all of the core +

    PyPy implements the Python language version 2.5. It supports all of the core language, passing Python test suite (with minor modifications that were -already accepted in main python in newer versions). It supports most -of commonly used Python standard library modules, list below.

    -

    PyPy does not support CPython C API, which means that third party +already accepted in the main python in newer versions). It supports most +of the commonly used Python standard library modules; details below.

    +

    PyPy does not support the CPython C API, which means that third party libraries for python, written in C, will not work.

    Standard library modules supported by PyPy, in alphabetical order:

      @@ -73,9 +73,9 @@

    Known differencies that are not going to be fixed:

      -
    • PyPy does not support refcounting semantics. The code below +

    • PyPy does not support refcounting semantics. The following code won't fill the file immediately, but only after a certain period -of time, when the GC will collect

      +of time, when the GC does a collection:

      open("filename", "w").write("stuff")

      The proper fix is

      f = open("filename", "w")
      f.write("stuff")
      f.close()
      @@ -85,8 +85,8 @@
    • We don't support certain attributes that were decided to be implementation-dependent. For example, gc.get_referrers does not exist. Others may have different behavior; for example, gc.enable and -gc.disable are supported, but they don't enable and disable GC, but -instead enable and disable running of finalizers.

      +gc.disable are supported, but they don't enable and disable the GC, but +instead just enable and disable the running of finalizers.

    • You can't attach a __del__ method to a class after its creation.

    • Modified: pypy/extradoc/pypy.org/download.html ============================================================================== --- pypy/extradoc/pypy.org/download.html (original) +++ pypy/extradoc/pypy.org/download.html Fri Mar 12 18:47:44 2010 @@ -48,10 +48,11 @@

      Download and install

      Here are the various binaries of PyPy 1.2 that we provide for x86 Linux, -Mac OS/X or Windows. This is the first release of PyPy containing JIT, hence +Mac OS/X or Windows. This is the first release of PyPy containing +a JIT compiler, hence the main goal is to try this out and see how it works for you. We put -a lot of effort into making JIT a stable piece of software and we don't -observe crashes, however, please consider it a beta version to try things out.

      +a lot of effort into making the JIT a stable piece of software and we don't +observe crashes; however, please consider it a beta version to try things out.

      • Download

        It is also possible to translate a version that includes both sandboxing and the JIT compiler, although as the JIT is relatively -complicated, this reduce a bit the level of confidence we can put in it.

        +complicated, this reduce a bit the level of confidence we can put in +the result.

        If your CPU is a 64-bit machine and you want to translate a 32-bit version of PyPy yourself, here are hints.

        The Windows and the native 64-bit versions both need testing and careful Modified: pypy/extradoc/pypy.org/features.html ============================================================================== --- pypy/extradoc/pypy.org/features.html (original) +++ pypy/extradoc/pypy.org/features.html Fri Mar 12 18:47:44 2010 @@ -48,9 +48,9 @@

        Features

        PyPy 1.2 implements Python 2.5. It supports all of the core -language, passing Python test suite (with minor modifications that were -already accepted in main python in newer versions). It supports most -of commonly used Python standard library modules. For known differences +language, passing the Python test suite (with minor modifications that were +already accepted in the main python in newer versions). It supports most +of the commonly used Python standard library modules. For known differences with CPython, see our compatibility page. If you are interested in helping with 2.6, 2.7 or 3.x features, contact us!

        PyPy 1.2 runs essentially only on Intel x86 (IA-32). On 64-bit platforms From arigo at codespeak.net Fri Mar 12 18:56:23 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 18:56:23 +0100 (CET) Subject: [pypy-svn] r72176 - pypy/extradoc/planning/1.2 Message-ID: <20100312175623.AAA56282BEE@codespeak.net> Author: arigo Date: Fri Mar 12 18:56:22 2010 New Revision: 72176 Modified: pypy/extradoc/planning/1.2/announcement.txt Log: Update the names at the end. Modified: pypy/extradoc/planning/1.2/announcement.txt ============================================================================== --- pypy/extradoc/planning/1.2/announcement.txt (original) +++ pypy/extradoc/planning/1.2/announcement.txt Fri Mar 12 18:56:22 2010 @@ -42,9 +42,17 @@ Linux, because of different versions of external .so dependencies), or if your platform is not supported, you can `try building from the source`_. -The PyPy release team (working of course for the full PyPy team), -Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc +The PyPy release team, + Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc + +Together with + + Antonio Cuni, Carl Friedrich Bolz, Holger Krekel and Samuele Pedroni + +and `many others`_. + +.. _`many others`: http://codespeak.net/pypy/dist/pypy/doc/contributor.html .. _`PyPy's 1.2 release`: http://pypy.org/ .. _`new PyPy website`: http://pypy.org/ .. _`various`: http://morepypy.blogspot.com/2010/03/hello.html From arigo at codespeak.net Fri Mar 12 19:10:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 19:10:02 +0100 (CET) Subject: [pypy-svn] r72177 - pypy/trunk/pypy/doc Message-ID: <20100312181002.B9354282BEE@codespeak.net> Author: arigo Date: Fri Mar 12 19:10:01 2010 New Revision: 72177 Modified: pypy/trunk/pypy/doc/release-1.2.0.txt Log: The release text, like I would like to e-mail it. Modified: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- pypy/trunk/pypy/doc/release-1.2.0.txt (original) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Fri Mar 12 19:10:01 2010 @@ -1,79 +1,93 @@ -============================================= -PyPy 1.2: Preview of Just-in-Time Compilation -============================================= +================================== +PyPy 1.2: Just-in-Time Compilation +================================== + +Welcome to the PyPy 1.2 release. The highlight of this +release is to be the first that ships with a Just-in-Time +compiler that is known to be faster than CPython (and unladen +swallow) on some real-world applications (or the best +benchmarks we could get for them). The main theme for the 1.2 +release is speed. + +Main site: + + http://pypy.org/ + +The JIT is stable and we don't observe crashes. Nevertheless +we would recommend you to treat it as beta software and as a +way to try out the JIT to see how it works for you. -Welcome to the PyPy 1.2 release. The highlight of this release is a -version of PyPy that includes a rather good JIT (Just-in-Time) Compiler. - -Download page: - - http://codespeak.net/pypy/dist/pypy/doc/download.html - -PyPy's Getting Started lives at: - - http://codespeak.net/pypy/dist/pypy/doc/getting-started.html Highlights of This Release ========================== - - JIT. XXX only on 32-bit Intel CPUs so far. - - http://morepypy.blogspot.com/search/label/jit - - - Graphs: - - http://speed.pypy.org/ - http://codespeak.net:8099/plotsummary.html - http://codespeak.net/pypy/jitplots.html - - - Improvements in GC and in our object model: we use much less memory - than CPython now - - http://morepypy.blogspot.com/2009/10/gc-improvements.html - http://? for the object model, e.g. sharingdict.py - +* The JIT compiler. -Other Changes -============= - - - ? +* Various interpreter optimizations that improve performance + as well as help save memory. - - CLI+JIT not included in the release +* Introducing a new PyPy website at http://pypy.org/ , made by + tav and improved by the PyPy team. - - Stackless incompatible with the JIT +* Introducing http://speed.pypy.org/ , a new service that + monitors our performance nightly, made by Miquel Torres. + +* There will be ubuntu packages on "PyPy's PPA" made by + Bartosz Skowron; however various troubles prevented us from + having them as of now. + +Known JIT problems (or why you should consider this beta +software) are: + +* The only supported platform is 32bit x86 for now, we're + looking for help with other platforms. + +* It is still memory-hungry. There is no limit on the amount + of RAM that the assembler can consume; it is thus possible + (although unlikely) that the assembler ends up using + unreasonable amounts of memory. + +If you want to try PyPy, go to the "download page" on our +excellent new site at http://pypy.org/download.html and find +the binary for your platform. If the binary does not work +(e.g. on Linux, because of different versions of external .so +dependencies), or if your platform is not supported, you can +try building from the source. What is PyPy? ============= -Technically, PyPy is both a Python interpreter implementation and an -advanced compiler, or more precisely a framework for implementing dynamic -languages and generating virtual machines for them. - -The framework allows for alternative frontends as well as for alternative -backends, currently C, Java and .NET. For our main target "C", we can -"mix in" different garbage collectors and threading models, -including micro-threads aka "Stackless". The inherent complexity that -arises from this ambitious approach is mostly kept away from the Python -interpreter implementation, our main frontend. - -The focus of this release is the introduction of a new transformation, -the JIT Compiler Generator, which is able to produce a JIT Compiler for -any interpreter frontend, given a very small number of hand-written hints. - -Socially, PyPy is a collaborative effort of many individuals working -together in a distributed and sprint-driven way since 2003. PyPy would -not have gotten as far as it has without the coding, feedback and -general support from numerous people. - - - -Have fun, - - the PyPy release team, [in alphabetical order] - - Amaury Forgeot d'Arc, Antonio Cuni, Armin Rigo, Carl Friedrich Bolz, - Holger Krekel, Maciek Fijalkowski, Samuele Pedroni +Technically, PyPy is both a Python interpreter implementation +and an advanced compiler, or more precisely a framework for +implementing dynamic languages and generating virtual machines +for them. + +The framework allows for alternative frontends as well as for +alternative backends, currently C, Java and .NET. For our +main target "C", we can "mix in" different garbage collectors +and threading models, including micro-threads aka "Stackless". +The inherent complexity that arises from this ambitious +approach is mostly kept away from the Python interpreter +implementation, our main frontend. + +The focus of this release is the introduction of a new +transformation, the JIT Compiler Generator, which is able to +produce a JIT Compiler for any interpreter frontend, given a +very small number of hand-written hints. + +Socially, PyPy is a collaborative effort of many individuals +working together in a distributed and sprint-driven way since +2003. PyPy would not have gotten as far as it has without the +coding, feedback and general support from numerous people. + + +The PyPy release team, + Armin Rigo, Maciej Fijalkowski and Amaury Forgeot d'Arc + +Together with + Antonio Cuni, Carl Friedrich Bolz, Holger Krekel and + Samuele Pedroni - and many others: +and many others: http://codespeak.net/pypy/dist/pypy/doc/contributor.html From arigo at codespeak.net Fri Mar 12 19:14:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 19:14:26 +0100 (CET) Subject: [pypy-svn] r72178 - pypy/trunk/pypy/doc Message-ID: <20100312181426.3B588282BEE@codespeak.net> Author: arigo Date: Fri Mar 12 19:14:24 2010 New Revision: 72178 Modified: pypy/trunk/pypy/doc/release-1.2.0.txt Log: Kill this part. Modified: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- pypy/trunk/pypy/doc/release-1.2.0.txt (original) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Fri Mar 12 19:14:24 2010 @@ -63,14 +63,6 @@ implementing dynamic languages and generating virtual machines for them. -The framework allows for alternative frontends as well as for -alternative backends, currently C, Java and .NET. For our -main target "C", we can "mix in" different garbage collectors -and threading models, including micro-threads aka "Stackless". -The inherent complexity that arises from this ambitious -approach is mostly kept away from the Python interpreter -implementation, our main frontend. - The focus of this release is the introduction of a new transformation, the JIT Compiler Generator, which is able to produce a JIT Compiler for any interpreter frontend, given a From arigo at codespeak.net Fri Mar 12 19:17:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 19:17:58 +0100 (CET) Subject: [pypy-svn] r72179 - pypy/trunk/pypy/doc Message-ID: <20100312181758.E9BA6282BEE@codespeak.net> Author: arigo Date: Fri Mar 12 19:17:57 2010 New Revision: 72179 Modified: pypy/trunk/pypy/doc/release-1.2.0.txt Log: Reduce. Modified: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- pypy/trunk/pypy/doc/release-1.2.0.txt (original) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Fri Mar 12 19:17:57 2010 @@ -61,12 +61,9 @@ Technically, PyPy is both a Python interpreter implementation and an advanced compiler, or more precisely a framework for implementing dynamic languages and generating virtual machines -for them. - -The focus of this release is the introduction of a new -transformation, the JIT Compiler Generator, which is able to -produce a JIT Compiler for any interpreter frontend, given a -very small number of hand-written hints. +for them. The focus of this release is the introduction of a +new transformation, the JIT Compiler Generator, and its +application to the Python interpreter. Socially, PyPy is a collaborative effort of many individuals working together in a distributed and sprint-driven way since From arigo at codespeak.net Fri Mar 12 19:23:56 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 12 Mar 2010 19:23:56 +0100 (CET) Subject: [pypy-svn] r72180 - pypy/trunk/pypy/doc Message-ID: <20100312182356.70984282BEE@codespeak.net> Author: arigo Date: Fri Mar 12 19:23:55 2010 New Revision: 72180 Modified: pypy/trunk/pypy/doc/release-1.2.0.txt Log: Reformat in slightly wider lines. Modified: pypy/trunk/pypy/doc/release-1.2.0.txt ============================================================================== --- pypy/trunk/pypy/doc/release-1.2.0.txt (original) +++ pypy/trunk/pypy/doc/release-1.2.0.txt Fri Mar 12 19:23:55 2010 @@ -2,20 +2,19 @@ PyPy 1.2: Just-in-Time Compilation ================================== -Welcome to the PyPy 1.2 release. The highlight of this -release is to be the first that ships with a Just-in-Time -compiler that is known to be faster than CPython (and unladen -swallow) on some real-world applications (or the best -benchmarks we could get for them). The main theme for the 1.2 -release is speed. +Welcome to the PyPy 1.2 release. The highlight of this release is +to be the first that ships with a Just-in-Time compiler that is +known to be faster than CPython (and unladen swallow) on some +real-world applications (or the best benchmarks we could get for +them). The main theme for the 1.2 release is speed. Main site: http://pypy.org/ -The JIT is stable and we don't observe crashes. Nevertheless -we would recommend you to treat it as beta software and as a -way to try out the JIT to see how it works for you. +The JIT is stable and we don't observe crashes. Nevertheless we +would recommend you to treat it as beta software and as a way to try +out the JIT to see how it works for you. Highlights of This Release @@ -36,8 +35,8 @@ Bartosz Skowron; however various troubles prevented us from having them as of now. -Known JIT problems (or why you should consider this beta -software) are: + +Known JIT problems (or why you should consider this beta software): * The only supported platform is 32bit x86 for now, we're looking for help with other platforms. @@ -47,28 +46,28 @@ (although unlikely) that the assembler ends up using unreasonable amounts of memory. -If you want to try PyPy, go to the "download page" on our -excellent new site at http://pypy.org/download.html and find -the binary for your platform. If the binary does not work -(e.g. on Linux, because of different versions of external .so -dependencies), or if your platform is not supported, you can -try building from the source. + +If you want to try PyPy, go to the "download page" on our excellent +new site at http://pypy.org/download.html and find the binary for +your platform. If the binary does not work (e.g. on Linux, because +of different versions of external .so dependencies), or if your +platform is not supported, you can try building from the source. What is PyPy? ============= -Technically, PyPy is both a Python interpreter implementation -and an advanced compiler, or more precisely a framework for -implementing dynamic languages and generating virtual machines -for them. The focus of this release is the introduction of a -new transformation, the JIT Compiler Generator, and its -application to the Python interpreter. - -Socially, PyPy is a collaborative effort of many individuals -working together in a distributed and sprint-driven way since -2003. PyPy would not have gotten as far as it has without the -coding, feedback and general support from numerous people. +Technically, PyPy is both a Python interpreter implementation and an +advanced compiler, or more precisely a framework for implementing +dynamic languages and generating virtual machines for them. The +focus of this release is the introduction of a new transformation, +the JIT Compiler Generator, and its application to the Python +interpreter. + +Socially, PyPy is a collaborative effort of many individuals working +together in a distributed and sprint-driven way since 2003. PyPy +would not have gotten as far as it has without the coding, feedback +and general support from numerous people. The PyPy release team, From fijal at codespeak.net Fri Mar 12 20:09:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 20:09:26 +0100 (CET) Subject: [pypy-svn] r72181 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100312190926.7700C282BEF@codespeak.net> Author: fijal Date: Fri Mar 12 20:09:25 2010 New Revision: 72181 Modified: pypy/trunk/pypy/jit/metainterp/test/test_list.py Log: Kill resizable-list tests. The reason is that they mostly pass without correct support for resizable lists, so they're of no use as they are. Modified: pypy/trunk/pypy/jit/metainterp/test/test_list.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_list.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_list.py Fri Mar 12 20:09:25 2010 @@ -118,266 +118,6 @@ assert res == f(10) py.test.skip("'[non-null] * n' gives a residual call so far") self.check_loops(setarrayitem_gc=0, getarrayitem_gc=0, call=0) - - def test_append_pop(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [] - lst.append(5) - lst.append(n) - lst[0] -= len(lst) - three = lst[0] - n = lst.pop() - three - return n - res = self.meta_interp(f, [31]) - assert res == -2 - self.check_all_virtualized() - - def test_insert(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [1, 2, 3] - lst.insert(0, n) - n = lst[0] - 1 - lst.pop() - # last pop is needed, otherwise it won't work - return n - res = self.meta_interp(f, [33]) - assert res == f(33) - self.check_all_virtualized() - - def test_nonzero(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [1, 2, 3] - lst.insert(0, n) - # nonzero should go away - if not lst: - return -33 - n = lst[0] - 1 - lst.pop() - # last pop is needed, otherwise it won't work - return n - res = self.meta_interp(f, [33]) - assert res == f(33) - self.check_all_virtualized() - self.check_loops(listnonzero=0, guard_true=1, guard_false=0) - - def test_append_pop_rebuild(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [] - lst.append(5) - lst.append(n) - lst[0] -= len(lst) - three = lst[0] - n = lst.pop() - three - if n == 2: - return n + lst.pop() - return n - res = self.meta_interp(f, [31]) - assert res == -2 - self.check_all_virtualized() - - def test_list_escapes(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while True: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [] - lst.append(n) - n = lst.pop() - 3 - if n < 0: - return len(lst) - res = self.meta_interp(f, [31]) - assert res == 0 - self.check_all_virtualized() - - def test_list_reenters(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [] - lst.append(n) - if n < 10: - lst[-1] = n-1 - n = lst.pop() - 3 - return n - res = self.meta_interp(f, [31]) - assert res == -1 - self.check_all_virtualized() - - def test_cannot_merge(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - lst = [] - if n < 20: - lst.append(n-3) - if n > 5: - lst.append(n-4) - n = lst.pop() - return n - res = self.meta_interp(f, [30]) - assert res == -1 - self.check_all_virtualized() - - def test_list_escapes(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def g(l): - pass - - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - l = [] - l.append(3) - g(l) - n -= 1 - return n - res = self.meta_interp(f, [30], policy=StopAtXPolicy(g)) - assert res == 0 - self.check_loops(append=1) - - def test_list_escapes_various_ops(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def g(l): - pass - - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - l = [] - l.append(3) - l.append(1) - n -= l.pop() - n -= l[0] - if l: - g(l) - n -= 1 - return n - res = self.meta_interp(f, [30], policy=StopAtXPolicy(g)) - assert res == 0 - self.check_loops(append=2) - - def test_list_escapes_find_nodes(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n']) - def g(l): - pass - - def f(n): - while n > 0: - jitdriver.can_enter_jit(n=n) - jitdriver.jit_merge_point(n=n) - l = [0] * n - l.append(3) - l.append(1) - n -= l.pop() - n -= l[-1] - if l: - g(l) - n -= 1 - return n - res = self.meta_interp(f, [30], policy=StopAtXPolicy(g)) - assert res == 0 - self.check_loops(append=2) - - def test_stuff_escapes_via_setitem(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n', 'l']) - class Stuff(object): - def __init__(self, x): - self.x = x - - def f(n): - l = [None] - while n > 0: - jitdriver.can_enter_jit(n=n, l=l) - jitdriver.jit_merge_point(n=n, l=l) - s = Stuff(3) - l.append(s) - n -= l[0].x - return n - res = self.meta_interp(f, [30]) - assert res == 0 - self.check_loops(append=1) - - def test_virtual_escaping_via_list(self): - py.test.skip("unsupported") - jitdriver = JitDriver(greens = [], reds = ['n', 'l']) - class Stuff(object): - def __init__(self, x): - self.x = x - - def f(n): - l = [Stuff(n-i) for i in range(n)] - - while n > 0: - jitdriver.can_enter_jit(n=n, l=l) - jitdriver.jit_merge_point(n=n, l=l) - s = l.pop() - n -= s.x - - res = self.meta_interp(f, [20]) - assert res == f(20) - self.check_loops(pop=1, getfield_gc=1) - - def test_extend(self): - py.test.skip("XXX") - def f(n): - while n > 0: - lst = [5, 2] - lst.extend([6, 7, n - 10]) - n = lst.pop() - return n - res = self.meta_interp(f, [33], exceptions=False) - assert res == -7 - self.check_all_virtualized() - - def test_single_list(self): - py.test.skip("in-progress") - def f(n): - lst = [n] * n - while n > 0: - n = lst.pop() - lst.append(n - 10) - a = lst.pop() - b = lst.pop() - return a * b - res = self.meta_interp(f, [37], exceptions=False) - assert res == -13 * 37 - self.check_all_virtualized() - - class TestOOtype(ListTests, OOJitMixin): pass From xoraxax at codespeak.net Fri Mar 12 20:56:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 12 Mar 2010 20:56:21 +0100 (CET) Subject: [pypy-svn] r72182 - pypy/benchmarks/psyco Message-ID: <20100312195621.93EBA282BF1@codespeak.net> Author: xoraxax Date: Fri Mar 12 20:56:20 2010 New Revision: 72182 Added: pypy/benchmarks/psyco/ pypy/benchmarks/psyco/python_with_psyco.sh (contents, props changed) pypy/benchmarks/psyco/sitecustomize.py Log: Add a way of running psyco. Added: pypy/benchmarks/psyco/python_with_psyco.sh ============================================================================== --- (empty file) +++ pypy/benchmarks/psyco/python_with_psyco.sh Fri Mar 12 20:56:20 2010 @@ -0,0 +1,2 @@ +#!/bin/sh +PYTHONPATH=`cd psyco; pwd` python "$@" Added: pypy/benchmarks/psyco/sitecustomize.py ============================================================================== --- (empty file) +++ pypy/benchmarks/psyco/sitecustomize.py Fri Mar 12 20:56:20 2010 @@ -0,0 +1,2 @@ +import psyco +psyco.profile() From xoraxax at codespeak.net Fri Mar 12 21:02:52 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 12 Mar 2010 21:02:52 +0100 (CET) Subject: [pypy-svn] r72183 - pypy/benchmarks/psyco Message-ID: <20100312200252.A6E72282BF1@codespeak.net> Author: xoraxax Date: Fri Mar 12 21:02:15 2010 New Revision: 72183 Modified: pypy/benchmarks/psyco/python_with_psyco.sh Log: Respect set PYTHONPATH. Modified: pypy/benchmarks/psyco/python_with_psyco.sh ============================================================================== --- pypy/benchmarks/psyco/python_with_psyco.sh (original) +++ pypy/benchmarks/psyco/python_with_psyco.sh Fri Mar 12 21:02:15 2010 @@ -1,2 +1,2 @@ #!/bin/sh -PYTHONPATH=`cd psyco; pwd` python "$@" +PYTHONPATH=`cd psyco; pwd`:$PYTHONPATH python "$@" From fijal at codespeak.net Fri Mar 12 21:03:25 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 21:03:25 +0100 (CET) Subject: [pypy-svn] r72184 - pypy/benchmarks Message-ID: <20100312200325.7E282282BF2@codespeak.net> Author: fijal Date: Fri Mar 12 21:03:16 2010 New Revision: 72184 Modified: pypy/benchmarks/runner.py Log: Add a --fast option Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Mar 12 21:03:16 2010 @@ -11,11 +11,13 @@ def run_and_store(benchmark_set, result_filename, pypy_c_path, revision=0, options='', branch='trunk', args='', upload=False, - force_host=None): + force_host=None, fast=False): funcs = perf.BENCH_FUNCS.copy() funcs.update(perf._FindAllBenchmarks(benchmarks.__dict__)) opts = ['-b', ','.join(benchmark_set), '--inherit_env=PATH', '--no_charts'] + if fast: + opts += ['--fast'] if args: opts += ['--args', args] opts += [sys.executable, pypy_c_path] @@ -82,6 +84,8 @@ help="Upload results to speed.pypy.org") parser.add_option("--force-host", default=None, action="store", help="Force the hostname") + parser.add_option("--fast", default=False, action="store_true", + help="Run shorter benchmark runs") options, args = parser.parse_args(argv) benchmarks = options.benchmarks.split(',') for benchmark in benchmarks: @@ -89,7 +93,7 @@ raise WrongBenchmark(benchmark) run_and_store(benchmarks, options.output_filename, options.pypy_c, options.revision, args=options.args, upload=options.upload, - force_host=options.force_host) + force_host=options.force_host, fast=options.fast) if __name__ == '__main__': main(sys.argv[1:]) From fijal at codespeak.net Fri Mar 12 21:14:23 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 21:14:23 +0100 (CET) Subject: [pypy-svn] r72185 - pypy/benchmarks/own/twisted Message-ID: <20100312201423.168E3282BF2@codespeak.net> Author: fijal Date: Fri Mar 12 21:14:00 2010 New Revision: 72185 Modified: pypy/benchmarks/own/twisted/benchlib.py Log: Fix the issue with warmup being counted as iterations Modified: pypy/benchmarks/own/twisted/benchlib.py ============================================================================== --- pypy/benchmarks/own/twisted/benchlib.py (original) +++ pypy/benchmarks/own/twisted/benchlib.py Fri Mar 12 21:14:00 2010 @@ -60,7 +60,7 @@ options = BenchmarkOptions() options.parseOptions(argv[1:]) duration = options['duration'] - jobs = [f] * options['iterations'] + jobs = [f] * (options['iterations'] + options['warmup']) d = Deferred() def work(res, counter): try: From xoraxax at codespeak.net Fri Mar 12 21:50:17 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 12 Mar 2010 21:50:17 +0100 (CET) Subject: [pypy-svn] r72186 - pypy/build/bot2/pypybuildbot Message-ID: <20100312205017.68686282BF5@codespeak.net> Author: xoraxax Date: Fri Mar 12 21:50:15 2010 New Revision: 72186 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Add pscyo to JITBenchmark Build Factory. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Fri Mar 12 21:50:15 2010 @@ -156,7 +156,18 @@ self.addStep(transfer.FileUpload(slavesrc="benchmarks/result.json", masterdest=WithProperties(resfile), workdir=".")) - + + self.addStep(ShellCmd( + description="run benchmarks on top of python with psyco", + command=["python", "runner.py", '--output-filename', 'result.json', + '--pypy-c', 'psyco/python_with_psyco.sh', + '--revision', WithProperties('%(got_revision)s'), + '--upload', '--force-host', 'bigdog', + '--branch', WithProperties('%(branch)s'), + ], + workdir='./benchmarks', + haltOnFailure=True)) + self.addStep(ShellCmd( description="run benchmarks 1", command=["python", "pypy/translator/benchmark/jitbench.py", From xoraxax at codespeak.net Fri Mar 12 21:59:06 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 12 Mar 2010 21:59:06 +0100 (CET) Subject: [pypy-svn] r72187 - pypy/benchmarks Message-ID: <20100312205906.7FA22282BF3@codespeak.net> Author: xoraxax Date: Fri Mar 12 21:59:04 2010 New Revision: 72187 Modified: pypy/benchmarks/runner.py Log: Derive correct name for psyco run. Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Mar 12 21:59:04 2010 @@ -38,11 +38,15 @@ name = "pypy-c" else: name = "pypy-c-jit" + optionsname = "gc=hybrid" + if "psyco.sh" in args: + name = "python-psyco-profile" + optionsname = "" if force_host is not None: host = force_host else: host = socket.gethostname() - save('pypy', revision, res, options, branch, name, "gc=hybrid", host) + save('pypy', revision, res, options, branch, name, optionsname, host) BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', 'rietveld', 'html5lib', 'ai'] From fijal at codespeak.net Fri Mar 12 22:28:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 22:28:17 +0100 (CET) Subject: [pypy-svn] r72188 - in pypy/trunk/pypy/rlib: . test Message-ID: <20100312212817.68A0E282BF3@codespeak.net> Author: fijal Date: Fri Mar 12 22:28:15 2010 New Revision: 72188 Modified: pypy/trunk/pypy/rlib/rbigint.py pypy/trunk/pypy/rlib/test/test_rbigint.py Log: (reported by fredrik johansson) A test and a fix for slightly overzelous assertion Modified: pypy/trunk/pypy/rlib/rbigint.py ============================================================================== --- pypy/trunk/pypy/rlib/rbigint.py (original) +++ pypy/trunk/pypy/rlib/rbigint.py Fri Mar 12 22:28:15 2010 @@ -914,7 +914,7 @@ t3 = _k_mul(t1, t2) del t1, t2 - assert t3.sign ==1 + assert t3.sign >=0 # Add t3. It's not obvious why we can't run out of room here. # See the (*) comment after this function. Modified: pypy/trunk/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rbigint.py (original) +++ pypy/trunk/pypy/rlib/test/test_rbigint.py Fri Mar 12 22:28:15 2010 @@ -314,6 +314,15 @@ '-!....!!..!!..!.!!.!......!...!...!!!........!') assert x.format('abcdefghijkl', '<<', '>>') == '-<>' + def test_bug_1(self): + a = rbigint.fromlong(-260566012002303321722013103575165611802035413114370523571517985970903119146285215291155533416475427807866974423149439841327725756828005658754191295994809087809320280074294681950026758288312811442356042692340807896417550222700067702753579399761784070474131037635149818948168511691070322953335739176272622910365829586902906224907432253591195717349172746433645917252849956470742043097671857488808687984974936937393198531638816746133375496901061105863168552515536868445659801937921320743439816979399954242291177429500378469191475860257584018420786462583814660948295622420456034201723416326423603335962947265565263130943743607845486466656418476418168470250055928378188550753407412799673743058221743671551255616401922924945339716159856273901552124064212280377021704945248469685731959689385127980398007781532220934759272116712735714960453264108373398671551492381335420245663126153660439132147185782037977502460780371596093655257982404062421193485596889355995886829663760398816634042131190521665958820147480841884648364911172419526690252752123997784474398064390304387861348712272377394239798859940158400355446891875253301687364211377544588264334532480752608170448214614824592743195324811005568687376657357775314753082365101450518250246694522659852514124844993887610246455390654886001947723458056036434568491624885628458493463036457076876557994173530887569689636475150085157584896384317149712863001575924410465356365220744359819651023350511856985665413799837139110207713222637419493822305417294231235755804223570090901279843944562993668494067416472862544255191694922740021466785813415839038537636203252434616410465425882750379236899419433481221219910352699544289818155750465496884035520473224175838968242973751544180489601650413296015651616296834725022936721050374837209645923011799078406180765136254224653160432350485532916558236511187886040205728660413810261023410048197904230010446088642876209717987090887740019976421912592014066600375956412103968560631965074024041620753826920381707525361879673445199503678061708391707896640363885748625247991660850390946150221513913729996091173773133131890225189064630986207916656744202551412451503273356101322462935617885275965853144343444704926691669657273293204666703512898072198258683719706285195069835543493502675161032489116187622069692993654200740685652627157360996959130403453347654083224412248043390793368967143340589648611252149478198894261334863884457393059141958486145451183004263823354652969965183462963726448733474469749514798522906424890883724926780202541044258203022886876020595422485151804950409950166755366874555828434740032171004838233809398853178488772731722647248612394324321149390505386951062179235246676031381046783794175796805080047738725286430898862883355470814692593559655069839453890111470642889098994389005946762316395275104458893107707110318839219905324157399932418015510323560907704798236836452155437817898814729188459245265619792043305147965178962411969228220664984934132957809193796871874171530228091837207719711362636305927916484527244928543234389063858371939012739858432000000) + + b = rbigint.fromlong(4) + + c = rbigint.fromlong(-106338239662793259730840081832295065771498816856940833696008165438815584980417686604608895346971884917769394031927561256725298929772711322879321393361696892049088965909181189736595867761347336019083746883127398251219384697894361161880597010006115562788942887618399114955271064878243102711874111058553462221395610761115873783457057812896391268438235444365991417075573732724100004047346784535037202050299531029591233086252349804548018155384835618742066822895556578137983546805076058353099547216512597408658946637718054915179937028899202964603576928551959262426346921004319846578906414772153517775387280861867487721363107740289707055950184419061249517558075330964421972823597291877332113158897302951144315480978860428747061439209765294730056119323718330270866241907812176527650320215232153341169940994430206379664550756722308581528186445619877248999398977789445715595671183883983268410651963136012836142558863971524201994294408478883247731406955241176141981742990603952556991912216949229945213071071983247958605165780107344396217423285452800) + + assert a.mul(b).mul(c).tolong() == 110832524129116782583364562456977640731335756529609088759378295006704772245974743173511644458675057302079987629835792236278312771678692303989361636542809838735194579106811404379614655739026463972679329139434164586374108475206967844097441160213284504934202480180032139888482444764983319216438433537832078516985619574162213721865744106517175234637261790280236913670178022378625016733361416185038455904438888246857878950470952325614982157170485741313910674393245003830392267085210311799551545972523346707387178520024611549981852670315070547440401122501891931825875960462166390275427684496325053195440865642204367994829293604398903046728164723158551453976182016937198123809176742966562888182432196414166400096652509342321321743476843344058627686730464867211258480704776704498446616101796263760178703227236505673451858701727913112759267764109714995818122458479126636108139321203958668185214950588580207103541950431274794566843359440350943752742082562538769212434294327810435270399438986112495616227923737414728798069933714673871391498110177949207547505033136836458634606312538096687797027733387424125878584385636111818223911900033354524034387542607682136576871579302279784953384936126882542253555140527486205141616943792484401155746547215597129490560806172364270767368990056371932228780665959134392102455377841234028978996308058186505194783650130179928673727012488256080004895653886144332872432289180496212904959975676585180012865990856545788985871243661381800148419972031058947277513438199225648529875646111686166176519979855679554344140264010483415463326100676133077809735840466471022613923792057235108707948400407624287331530986889046800817902279069703559833421581331256230884071179598459785625245650782029029322150238995195521227505990817653610469722901339231958298390284876126014159379033287075519462149243271172963871032844781784225603388136263417588981496551374805239987026987313762069576871742865088508552110890580500720033327845072452424251933683127950277588406114514844979948727526706389888421544523362606742419244747509102087639447513471188108241157864242701335645555026346619245699752666285865081977746566880559621759751595020851093674855777825451087504404795410611432959365368919126606768430328681016998624963878159228600896476855567188634084921197529066160362616693921167843075792824209694269220559843282666693049363809669507785196417549088417499875428569887061842530632366731211920496861835081751081842566818397316345926010655462157108750820970335096339414909824916313255708868878066428162448128721439720699956849305447074147346861983811454157772370142260519018784555066718855368418469670174688776370877035479525356163764475258378975158984871528660286361965641503971983346012081939513003180866443286265869046461908753885889743448744320141501611168369982279186025200319384649405474996576807017922093590932514280363660550227287802611494334334607843323216686446826866447311048152176684331349978510675393988261003953873381091617333523977851570885851719036027366439199079878330408900672719175802907289051303375145535553930031626633762994181239987601184562172550477892685669393404111413175213787178098834254167127624253002981496188936840854096027552855011170366261745499495417813144239077455025835453607885002118545216683747855456386109509751819274073863878470281232518189103557806573352768345515244126718703747172619569007522184689496709008855313559867161158579502656536285666843995155026521610393549572974321882301537225738400691179905702280583119045478250270608753115619081672106397626905258492908537976623550592167132205686242236595251736145299604679380289665497374792748814099937488988552367986787677665998385383608256021488822227572444336678008598743792369799266926833042608329505013007907469005128713651150644761489785642344749398016890987457554939180946052125679983599966774606430591989594901778520067217343641063899668851213095805105740570942673366384498478828587645324595977304487968297570444369020807943787596717818846249373957402470969494527872843184588264064266126564410921857079085523025929016927582700388097395606532665822492862195671710755988072038400000000 + class TestInternalFunctions(object): def test__inplace_divrem1(self): From fijal at codespeak.net Fri Mar 12 22:37:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 22:37:16 +0100 (CET) Subject: [pypy-svn] r72189 - pypy/trunk/pypy/rlib/test Message-ID: <20100312213716.2AAF6282BF3@codespeak.net> Author: fijal Date: Fri Mar 12 22:37:15 2010 New Revision: 72189 Modified: pypy/trunk/pypy/rlib/test/test_rbigint.py Log: simplify the test (thanks frederik) Modified: pypy/trunk/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rbigint.py (original) +++ pypy/trunk/pypy/rlib/test/test_rbigint.py Fri Mar 12 22:37:15 2010 @@ -314,15 +314,10 @@ '-!....!!..!!..!.!!.!......!...!...!!!........!') assert x.format('abcdefghijkl', '<<', '>>') == '-<>' - def test_bug_1(self): - a = rbigint.fromlong(-260566012002303321722013103575165611802035413114370523571517985970903119146285215291155533416475427807866974423149439841327725756828005658754191295994809087809320280074294681950026758288312811442356042692340807896417550222700067702753579399761784070474131037635149818948168511691070322953335739176272622910365829586902906224907432253591195717349172746433645917252849956470742043097671857488808687984974936937393198531638816746133375496901061105863168552515536868445659801937921320743439816979399954242291177429500378469191475860257584018420786462583814660948295622420456034201723416326423603335962947265565263130943743607845486466656418476418168470250055928378188550753407412799673743058221743671551255616401922924945339716159856273901552124064212280377021704945248469685731959689385127980398007781532220934759272116712735714960453264108373398671551492381335420245663126153660439132147185782037977502460780371596093655257982404062421193485596889355995886829663760398816634042131190521665958820147480841884648364911172419526690252752123997784474398064390304387861348712272377394239798859940158400355446891875253301687364211377544588264334532480752608170448214614824592743195324811005568687376657357775314753082365101450518250246694522659852514124844993887610246455390654886001947723458056036434568491624885628458493463036457076876557994173530887569689636475150085157584896384317149712863001575924410465356365220744359819651023350511856985665413799837139110207713222637419493822305417294231235755804223570090901279843944562993668494067416472862544255191694922740021466785813415839038537636203252434616410465425882750379236899419433481221219910352699544289818155750465496884035520473224175838968242973751544180489601650413296015651616296834725022936721050374837209645923011799078406180765136254224653160432350485532916558236511187886040205728660413810261023410048197904230010446088642876209717987090887740019976421912592014066600375956412103968560631965074024041620753826920381707525361879673445199503678061708391707896640363885748625247991660850390946150221513913729996091173773133131890225189064630986207916656744202551412451503273356101322462935617885275965853144343444704926691669657273293204666703512898072198258683719706285195069835543493502675161032489116187622069692993654200740685652627157360996959130403453347654083224412248043390793368967143340589648611252149478198894261334863884457393059141958486145451183004263823354652969965183462963726448733474469749514798522906424890883724926780202541044258203022886876020595422485151804950409950166755366874555828434740032171004838233809398853178488772731722647248612394324321149390505386951062179235246676031381046783794175796805080047738725286430898862883355470814692593559655069839453890111470642889098994389005946762316395275104458893107707110318839219905324157399932418015510323560907704798236836452155437817898814729188459245265619792043305147965178962411969228220664984934132957809193796871874171530228091837207719711362636305927916484527244928543234389063858371939012739858432000000) - - b = rbigint.fromlong(4) - - c = rbigint.fromlong(-106338239662793259730840081832295065771498816856940833696008165438815584980417686604608895346971884917769394031927561256725298929772711322879321393361696892049088965909181189736595867761347336019083746883127398251219384697894361161880597010006115562788942887618399114955271064878243102711874111058553462221395610761115873783457057812896391268438235444365991417075573732724100004047346784535037202050299531029591233086252349804548018155384835618742066822895556578137983546805076058353099547216512597408658946637718054915179937028899202964603576928551959262426346921004319846578906414772153517775387280861867487721363107740289707055950184419061249517558075330964421972823597291877332113158897302951144315480978860428747061439209765294730056119323718330270866241907812176527650320215232153341169940994430206379664550756722308581528186445619877248999398977789445715595671183883983268410651963136012836142558863971524201994294408478883247731406955241176141981742990603952556991912216949229945213071071983247958605165780107344396217423285452800) - - assert a.mul(b).mul(c).tolong() == 110832524129116782583364562456977640731335756529609088759378295006704772245974743173511644458675057302079987629835792236278312771678692303989361636542809838735194579106811404379614655739026463972679329139434164586374108475206967844097441160213284504934202480180032139888482444764983319216438433537832078516985619574162213721865744106517175234637261790280236913670178022378625016733361416185038455904438888246857878950470952325614982157170485741313910674393245003830392267085210311799551545972523346707387178520024611549981852670315070547440401122501891931825875960462166390275427684496325053195440865642204367994829293604398903046728164723158551453976182016937198123809176742966562888182432196414166400096652509342321321743476843344058627686730464867211258480704776704498446616101796263760178703227236505673451858701727913112759267764109714995818122458479126636108139321203958668185214950588580207103541950431274794566843359440350943752742082562538769212434294327810435270399438986112495616227923737414728798069933714673871391498110177949207547505033136836458634606312538096687797027733387424125878584385636111818223911900033354524034387542607682136576871579302279784953384936126882542253555140527486205141616943792484401155746547215597129490560806172364270767368990056371932228780665959134392102455377841234028978996308058186505194783650130179928673727012488256080004895653886144332872432289180496212904959975676585180012865990856545788985871243661381800148419972031058947277513438199225648529875646111686166176519979855679554344140264010483415463326100676133077809735840466471022613923792057235108707948400407624287331530986889046800817902279069703559833421581331256230884071179598459785625245650782029029322150238995195521227505990817653610469722901339231958298390284876126014159379033287075519462149243271172963871032844781784225603388136263417588981496551374805239987026987313762069576871742865088508552110890580500720033327845072452424251933683127950277588406114514844979948727526706389888421544523362606742419244747509102087639447513471188108241157864242701335645555026346619245699752666285865081977746566880559621759751595020851093674855777825451087504404795410611432959365368919126606768430328681016998624963878159228600896476855567188634084921197529066160362616693921167843075792824209694269220559843282666693049363809669507785196417549088417499875428569887061842530632366731211920496861835081751081842566818397316345926010655462157108750820970335096339414909824916313255708868878066428162448128721439720699956849305447074147346861983811454157772370142260519018784555066718855368418469670174688776370877035479525356163764475258378975158984871528660286361965641503971983346012081939513003180866443286265869046461908753885889743448744320141501611168369982279186025200319384649405474996576807017922093590932514280363660550227287802611494334334607843323216686446826866447311048152176684331349978510675393988261003953873381091617333523977851570885851719036027366439199079878330408900672719175802907289051303375145535553930031626633762994181239987601184562172550477892685669393404111413175213787178098834254167127624253002981496188936840854096027552855011170366261745499495417813144239077455025835453607885002118545216683747855456386109509751819274073863878470281232518189103557806573352768345515244126718703747172619569007522184689496709008855313559867161158579502656536285666843995155026521610393549572974321882301537225738400691179905702280583119045478250270608753115619081672106397626905258492908537976623550592167132205686242236595251736145299604679380289665497374792748814099937488988552367986787677665998385383608256021488822227572444336678008598743792369799266926833042608329505013007907469005128713651150644761489785642344749398016890987457554939180946052125679983599966774606430591989594901778520067217343641063899668851213095805105740570942673366384498478828587645324595977304487968297570444369020807943787596717818846249373957402470969494527872843184588264064266126564410921857079085523025929016927582700388097395606532665822492862195671710755988072038400000000 - + def test_overzelous_assertion(self): + a = rbigint.fromlong(-1<<10000) + b = rbigint.fromlong(-1<<3000) + assert a.mul(b).tolong() == (-1<<10000)*(-1<<3000) class TestInternalFunctions(object): def test__inplace_divrem1(self): From fijal at codespeak.net Fri Mar 12 23:10:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 23:10:58 +0100 (CET) Subject: [pypy-svn] r72190 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100312221058.9C0A7282BF3@codespeak.net> Author: fijal Date: Fri Mar 12 23:10:57 2010 New Revision: 72190 Modified: pypy/trunk/pypy/objspace/std/complexobject.py pypy/trunk/pypy/objspace/std/test/test_complexobject.py Log: A test and a fix for complex repr Modified: pypy/trunk/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/complexobject.py (original) +++ pypy/trunk/pypy/objspace/std/complexobject.py Fri Mar 12 23:10:57 2010 @@ -252,9 +252,10 @@ app = gateway.applevel(""" import math + import sys def possint(f): ff = math.floor(f) - if f == ff: + if f == ff and abs(f) < sys.maxint: return int(ff) return f 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 Mar 12 23:10:57 2010 @@ -326,6 +326,7 @@ h.assertEqual(repr(1-6j), '(1-6j)') h.assertNotEqual(repr(-(1+0j)), '(-1+-0j)') + assert repr(complex(1e45)) == "(" + repr(1e45) + "+0j)" def test_neg(self): h = self.helper From fijal at codespeak.net Fri Mar 12 23:55:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 12 Mar 2010 23:55:52 +0100 (CET) Subject: [pypy-svn] r72191 - pypy/benchmarks Message-ID: <20100312225552.2FBFC282BF2@codespeak.net> Author: fijal Date: Fri Mar 12 23:55:50 2010 New Revision: 72191 Modified: pypy/benchmarks/benchmarks.py Log: Grumble, reduce number of web iterations Modified: pypy/benchmarks/benchmarks.py ============================================================================== --- pypy/benchmarks/benchmarks.py (original) +++ pypy/benchmarks/benchmarks.py Fri Mar 12 23:55:50 2010 @@ -48,7 +48,7 @@ _register_new_bm(name, name, globals(), **opts.get(name, {})) for name in ['web', 'names', 'iteration', 'tcp', 'pb']:#, 'accepts']: if name == 'web': - iteration_scaling = .12 + iteration_scaling = .07 else: iteration_scaling = .20 _register_new_bm_twisted(name, 'twisted_' + name, From fijal at codespeak.net Sat Mar 13 00:45:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 13 Mar 2010 00:45:58 +0100 (CET) Subject: [pypy-svn] r72192 - in pypy/trunk/pypy/module/__builtin__: . test Message-ID: <20100312234558.31E4F282BF2@codespeak.net> Author: fijal Date: Sat Mar 13 00:45:56 2010 New Revision: 72192 Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py pypy/trunk/pypy/module/__builtin__/test/test_descriptor.py Log: Use combination of __new__ and __init__ instead of just __new__ Modified: pypy/trunk/pypy/module/__builtin__/descriptor.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/descriptor.py (original) +++ pypy/trunk/pypy/module/__builtin__/descriptor.py Sat Mar 13 00:45:56 2010 @@ -96,7 +96,7 @@ ) class W_Property(Wrappable): - def __init__(self, space, w_fget, w_fset, w_fdel, w_doc): + def init(self, space, w_fget=None, w_fset=None, w_fdel=None, w_doc=None): self.w_fget = w_fget self.w_fset = w_fset self.w_fdel = w_fdel @@ -106,10 +106,10 @@ w_getter_doc = space.findattr(self.w_fget, space.wrap("__doc__")) if w_getter_doc is not None: self.w_doc = w_getter_doc + init.unwrap_spec = ['self', ObjSpace, W_Root, W_Root, W_Root, W_Root] 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) - W_Property.__init__(w_result, space, w_fget, w_fset, w_fdel, w_doc) return w_result new.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root, W_Root, W_Root] @@ -173,6 +173,7 @@ def delx(self): del self.__x x = property(getx, setx, delx, "I am the 'x' property.")''', __new__ = interp2app(W_Property.new.im_func), + __init__ = interp2app(W_Property.init), __get__ = interp2app(W_Property.get), __set__ = interp2app(W_Property.set), __delete__ = interp2app(W_Property.delete), 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 Sat Mar 13 00:45:56 2010 @@ -310,4 +310,18 @@ p.name = 0 assert p.name == 0 + def test_property_subclass_with_init(self): + l = [] + + def x(self): + l.append('x') + + class P(property): + def __init__(self): + property.__init__(self, x) + class X(object): + x = P() + + X().x + assert l From xoraxax at codespeak.net Sat Mar 13 02:31:53 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 13 Mar 2010 02:31:53 +0100 (CET) Subject: [pypy-svn] r72193 - pypy/benchmarks Message-ID: <20100313013153.6D82D282BF2@codespeak.net> Author: xoraxax Date: Sat Mar 13 02:31:50 2010 New Revision: 72193 Modified: pypy/benchmarks/runner.py Log: Fix runner.py to classify psyco results correctly. Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Sat Mar 13 02:31:50 2010 @@ -39,7 +39,7 @@ else: name = "pypy-c-jit" optionsname = "gc=hybrid" - if "psyco.sh" in args: + if "psyco.sh" in pypy_c_path: name = "python-psyco-profile" optionsname = "" if force_host is not None: From arigo at codespeak.net Sat Mar 13 09:55:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 09:55:57 +0100 (CET) Subject: [pypy-svn] r72194 - in pypy/trunk/pypy/module/sys: . test Message-ID: <20100313085557.5835A282BF3@codespeak.net> Author: arigo Date: Sat Mar 13 09:55:55 2010 New Revision: 72194 Added: pypy/trunk/pypy/module/sys/test/test_version.py (contents, props changed) Modified: pypy/trunk/pypy/module/sys/version.py Log: A fix for (among others I fear) git mirrors in which the REV turns up as an empty string. Added: pypy/trunk/pypy/module/sys/test/test_version.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/sys/test/test_version.py Sat Mar 13 09:55:55 2010 @@ -0,0 +1,5 @@ +from pypy.module.sys.version import rev2int + +def test_rev2int(): + assert rev2int("71630") == 71630 + assert rev2int("") == 0 Modified: pypy/trunk/pypy/module/sys/version.py ============================================================================== --- pypy/trunk/pypy/module/sys/version.py (original) +++ pypy/trunk/pypy/module/sys/version.py Sat Mar 13 09:55:55 2010 @@ -15,6 +15,18 @@ REV = """$LastChangedRevision$"""[22:-2] +def rev2int(rev): + try: + return int(rev) + except ValueError: + import py + from pypy.tool.ansi_print import ansi_log + log = py.log.Producer("version") + py.log.setconsumer("version", ansi_log) + log.ERROR("No subversion revision number available!") + log.ERROR("Hard-coding '0'") + return 0 + import pypy pypydir = os.path.dirname(os.path.abspath(pypy.__file__)) @@ -85,7 +97,7 @@ "Return the last-changed svn revision number." # NB. we hack the number directly out of the .svn directory to avoid # to depend on an external 'svn' executable in the path. - rev = int(REV) + rev = rev2int(REV) try: formatfile = os.path.join(pypydir, '.svn', 'format') if os.path.exists(formatfile): From arigo at codespeak.net Sat Mar 13 11:10:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 11:10:50 +0100 (CET) Subject: [pypy-svn] r72196 - pypy/trunk/pypy/module/__builtin__ Message-ID: <20100313101050.4885B282BF2@codespeak.net> Author: arigo Date: Sat Mar 13 11:10:48 2010 New Revision: 72196 Modified: pypy/trunk/pypy/module/__builtin__/functional.py Log: Remove duplication (this used to be "try: return x except: return x"). Add a general comment. Modified: pypy/trunk/pypy/module/__builtin__/functional.py ============================================================================== --- pypy/trunk/pypy/module/__builtin__/functional.py (original) +++ pypy/trunk/pypy/module/__builtin__/functional.py Sat Mar 13 11:10:48 2010 @@ -531,13 +531,9 @@ self.len, -self.step)) def _toint(space, w_obj): - # trying to support float arguments, just because CPython still does - try: - return space.int_w(space.int(w_obj)) - except OperationError, e: - if space.is_true(space.isinstance(w_obj, space.w_float)): - return space.int_w(space.int(w_obj)) - raise + # this also supports float arguments. CPython still does, too. + # needs a bit more thinking in general... + return space.int_w(space.int(w_obj)) W_XRange.typedef = TypeDef("xrange", __new__ = interp2app(W_XRange.descr_new.im_func), From arigo at codespeak.net Sat Mar 13 11:29:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 11:29:54 +0100 (CET) Subject: [pypy-svn] r72197 - pypy/trunk/pypy/lib Message-ID: <20100313102954.E76CC282BF2@codespeak.net> Author: arigo Date: Sat Mar 13 11:29:53 2010 New Revision: 72197 Modified: pypy/trunk/pypy/lib/cmath.py Log: Uh? Modified: pypy/trunk/pypy/lib/cmath.py ============================================================================== --- pypy/trunk/pypy/lib/cmath.py (original) +++ pypy/trunk/pypy/lib/cmath.py Sat Mar 13 11:29:53 2010 @@ -37,7 +37,6 @@ Return the hyperbolic arccosine of x.""" - z = complex() z = sqrt(_half) z = log(z*(sqrt(x+_one)+sqrt(x-_one))) return z+z @@ -59,7 +58,6 @@ Return the hyperbolic arc sine of x.""" - z = complex() z = sqrt(_half) z = log((z * (sqrt(x+_i)+sqrt((x-_i))) )) return z+z From arigo at codespeak.net Sat Mar 13 11:56:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 11:56:54 +0100 (CET) Subject: [pypy-svn] r72198 - pypy/trunk/pypy/lib Message-ID: <20100313105654.95CD9282BF2@codespeak.net> Author: arigo Date: Sat Mar 13 11:56:52 2010 New Revision: 72198 Modified: pypy/trunk/pypy/lib/cmath.py Log: Precompute sqrt(_half). Delicate tweaking: are there any test at all?? Modified: pypy/trunk/pypy/lib/cmath.py ============================================================================== --- pypy/trunk/pypy/lib/cmath.py (original) +++ pypy/trunk/pypy/lib/cmath.py Sat Mar 13 11:56:52 2010 @@ -37,8 +37,7 @@ Return the hyperbolic arccosine of x.""" - z = sqrt(_half) - z = log(z*(sqrt(x+_one)+sqrt(x-_one))) + z = log(_sqrt_half*(sqrt(x+_one)+sqrt(x-_one))) return z+z @@ -58,8 +57,7 @@ Return the hyperbolic arc sine of x.""" - z = sqrt(_half) - z = log((z * (sqrt(x+_i)+sqrt((x-_i))) )) + z = log((_sqrt_half * (sqrt(x+_i)+sqrt((x-_i))) )) return z+z @@ -183,6 +181,8 @@ imag = -s return complex(real, imag) +_sqrt_half = sqrt(_half) + def tan(x): """tan(x) From arigo at codespeak.net Sat Mar 13 16:33:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 16:33:05 +0100 (CET) Subject: [pypy-svn] r72201 - pypy/branch/jit-newx86 Message-ID: <20100313153305.F3BAF282BF2@codespeak.net> Author: arigo Date: Sat Mar 13 16:33:04 2010 New Revision: 72201 Added: pypy/branch/jit-newx86/ - copied from r72200, pypy/trunk/ Log: A branch to play again with removing multimethods in the x86 backend. From arigo at codespeak.net Sat Mar 13 16:56:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 13 Mar 2010 16:56:05 +0100 (CET) Subject: [pypy-svn] r72202 - in pypy/branch/jit-newx86/pypy/jit/backend/newx86: . test Message-ID: <20100313155605.40BA2282BF2@codespeak.net> Author: arigo Date: Sat Mar 13 16:56:03 2010 New Revision: 72202 Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/ (props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/__init__.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/assembler.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/runner.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/rx86.py - copied, changed from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/rx86.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/ (props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/__init__.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_runner.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_rx86.py - copied, changed from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/test/test_rx86.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_rx86_32_auto_encoding.py - copied, changed from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_rx86_64_auto_encoding.py - copied, changed from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/test/test_rx86_64_auto_encoding.py Log: Add again rx86.py and associated test files. This time, rx86 was modified to generate code in the other order, i.e. starting from the end. Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/__init__.py ============================================================================== Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/assembler.py ============================================================================== --- (empty file) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/assembler.py Sat Mar 13 16:56:03 2010 @@ -0,0 +1,18 @@ +from pypy.jit.backend.newx86.rx86 import R + + +class Assembler386(object): + + def __init__(self, cpu): + self.cpu = cpu + self.locations = {} + + def compile_loop(self, inputargs, operations, looptoken): + xxx + + +def is_reg(loc): + return loc >= 0 + +def is_stack(loc): + return loc < 0 Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/runner.py ============================================================================== --- (empty file) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/runner.py Sat Mar 13 16:56:03 2010 @@ -0,0 +1,20 @@ +from pypy.jit.backend.llsupport.llmodel import AbstractLLCPU +from pypy.jit.backend.newx86.assembler import Assembler386 + + +class CPU(AbstractLLCPU): + + def __init__(self, rtyper, stats, opts=None, translate_support_code=False, + gcdescr=None): + AbstractLLCPU.__init__(self, rtyper, stats, opts, + translate_support_code, gcdescr) + if opts is not None: + self.failargs_limit = opts.failargs_limit + else: + self.failargs_limit = 1000 + + def compile_loop(self, inputargs, operations, looptoken): + """Assemble the given loop, and update looptoken to point to + the compiled loop in assembler.""" + assembler = Assembler386(self) + assembler.compile_loop(inputargs, operations, looptoken) Copied: pypy/branch/jit-newx86/pypy/jit/backend/newx86/rx86.py (from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/rx86.py) ============================================================================== --- pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/rx86.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/rx86.py Sat Mar 13 16:56:03 2010 @@ -98,7 +98,7 @@ def encode_relative(mc, target, _, orbyte): assert orbyte == 0 - offset = target - (mc.tell() + 4) + offset = target - mc.tell() mc.writeimm32(offset) return 0 @@ -111,11 +111,11 @@ @specialize.arg(2) def encode_stack_bp(mc, offset, force_32bits, orbyte): if not force_32bits and single_byte(offset): - mc.writechar(chr(0x40 | orbyte | R.ebp)) mc.writeimm8(offset) + mc.writechar(chr(0x40 | orbyte | R.ebp)) else: - mc.writechar(chr(0x80 | orbyte | R.ebp)) mc.writeimm32(offset) + mc.writechar(chr(0x80 | orbyte | R.ebp)) return 0 def stack_bp(argnum, force_32bits=False): @@ -127,16 +127,16 @@ def encode_stack_sp(mc, offset, _, orbyte): SIB = chr((R.esp<<3) | R.esp) # use [esp+(no index)+offset] if offset == 0: - mc.writechar(chr(0x04 | orbyte)) mc.writechar(SIB) + mc.writechar(chr(0x04 | orbyte)) elif single_byte(offset): - mc.writechar(chr(0x44 | orbyte)) - mc.writechar(SIB) mc.writeimm8(offset) - else: - mc.writechar(chr(0x84 | orbyte)) mc.writechar(SIB) + mc.writechar(chr(0x44 | orbyte)) + else: mc.writeimm32(offset) + mc.writechar(SIB) + mc.writechar(chr(0x84 | orbyte)) return 0 def stack_sp(argnum): @@ -160,16 +160,16 @@ no_offset = False # end of 64-bits special cases if no_offset: - mc.writechar(chr(0x00 | orbyte | reg1)) if SIB >= 0: mc.writechar(chr(SIB)) + mc.writechar(chr(0x00 | orbyte | reg1)) elif single_byte(offset): - mc.writechar(chr(0x40 | orbyte | reg1)) - if SIB >= 0: mc.writechar(chr(SIB)) mc.writeimm8(offset) - else: - mc.writechar(chr(0x80 | orbyte | reg1)) if SIB >= 0: mc.writechar(chr(SIB)) + mc.writechar(chr(0x40 | orbyte | reg1)) + else: mc.writeimm32(offset) + if SIB >= 0: mc.writechar(chr(SIB)) + mc.writechar(chr(0x80 | orbyte | reg1)) return 0 def rex_mem_reg_plus_const(mc, (reg, offset), _): @@ -201,16 +201,16 @@ no_offset = False # end of 64-bits special case if no_offset: - mc.writechar(chr(0x04 | orbyte)) mc.writechar(SIB) + mc.writechar(chr(0x04 | orbyte)) elif single_byte(offset): - mc.writechar(chr(0x44 | orbyte)) - mc.writechar(SIB) mc.writeimm8(offset) - else: - mc.writechar(chr(0x84 | orbyte)) mc.writechar(SIB) + mc.writechar(chr(0x44 | orbyte)) + else: mc.writeimm32(offset) + mc.writechar(SIB) + mc.writechar(chr(0x84 | orbyte)) return 0 def rex_mem_reg_plus_scaled_reg_plus_const(mc, @@ -250,20 +250,17 @@ def insn(*encoding): def encode(mc, *args): - rexbyte = 0 - if mc.WORD == 8: - # compute the REX byte, if any - for encode_step, arg, extra, rex_step in encoding_steps: - if rex_step: - if arg is not None: - arg = args[arg-1] - rexbyte |= rex_step(mc, arg, extra) - args = (rexbyte,) + args # emit the bytes of the instruction + rexbyte = 0 orbyte = 0 for encode_step, arg, extra, rex_step in encoding_steps: if arg is not None: - arg = args[arg] + if arg == 0: + arg = rexbyte + else: + arg = args[arg-1] + if rex_step and mc.WORD == 8: + rexbyte |= rex_step(mc, arg, extra) orbyte = encode_step(mc, arg, extra, orbyte) assert orbyte == 0 # @@ -275,6 +272,7 @@ else: assert type(step) is tuple and len(step) == 4 encoding_steps.append(step) + encoding_steps.reverse() encoding_steps = unrolling_iterable(encoding_steps) return encode @@ -286,13 +284,13 @@ def common_modes(group): base = group * 8 char = chr(0xC0 | base) - INSN_ri8 = insn(rex_w, '\x83', register(1), char, immediate(2,'b')) - INSN_ri32= insn(rex_w, '\x81', register(1), char, immediate(2)) - INSN_rr = insn(rex_w, chr(base+1), register(2,8), register(1,1), '\xC0') - INSN_br = insn(rex_w, chr(base+1), register(2,8), stack_bp(1)) - INSN_rb = insn(rex_w, chr(base+3), register(1,8), stack_bp(2)) - INSN_bi8 = insn(rex_w, '\x83', orbyte(base), stack_bp(1), immediate(2,'b')) - INSN_bi32= insn(rex_w, '\x81', orbyte(base), stack_bp(1), immediate(2)) + INSN_ri8 = insn(rex_w, '\x83', char, register(1), immediate(2,'b')) + INSN_ri32= insn(rex_w, '\x81', char, register(1), immediate(2)) + INSN_rr = insn(rex_w, chr(base+1), '\xC0', register(2,8), register(1,1)) + INSN_br = insn(rex_w, chr(base+1), stack_bp(1), register(2,8)) + INSN_rb = insn(rex_w, chr(base+3), stack_bp(2), register(1,8)) + INSN_bi8 = insn(rex_w, '\x83', stack_bp(1), orbyte(base), immediate(2,'b')) + INSN_bi32= insn(rex_w, '\x81', stack_bp(1), orbyte(base), immediate(2)) def INSN_ri(mc, reg, immed): if single_byte(immed): @@ -323,38 +321,38 @@ self.writechar(chr(imm & 0xFF)) def writeimm16(self, imm): - self.writechar(chr(imm & 0xFF)) self.writechar(chr((imm >> 8) & 0xFF)) + self.writechar(chr(imm & 0xFF)) def writeimm32(self, imm): assert fits_in_32bits(imm) - self.writechar(chr(imm & 0xFF)) - self.writechar(chr((imm >> 8) & 0xFF)) - self.writechar(chr((imm >> 16) & 0xFF)) self.writechar(chr((imm >> 24) & 0xFF)) + self.writechar(chr((imm >> 16) & 0xFF)) + self.writechar(chr((imm >> 8) & 0xFF)) + self.writechar(chr(imm & 0xFF)) # ------------------------------ MOV ------------------------------ - MOV_ri = insn(rex_w, register(1), '\xB8', immediate(2, 'q')) - MOV_rr = insn(rex_w, '\x89', register(2,8), register(1), '\xC0') - MOV_br = insn(rex_w, '\x89', register(2,8), stack_bp(1)) - MOV_rb = insn(rex_w, '\x8B', register(1,8), stack_bp(2)) + MOV_ri = insn(rex_w, '\xB8', register(1), immediate(2, 'q')) + MOV_rr = insn(rex_w, '\x89', '\xC0', register(2,8), register(1)) + MOV_br = insn(rex_w, '\x89', stack_bp(1), register(2,8)) + MOV_rb = insn(rex_w, '\x8B', stack_bp(2), register(1,8)) # "MOV reg1, [reg2+offset]" and the opposite direction - MOV_rm = insn(rex_w, '\x8B', register(1,8), mem_reg_plus_const(2)) - MOV_mr = insn(rex_w, '\x89', register(2,8), mem_reg_plus_const(1)) - MOV_mi = insn(rex_w, '\xC7', orbyte(0<<3), mem_reg_plus_const(1), - immediate(2, 'i')) + MOV_rm = insn(rex_w, '\x8B', mem_reg_plus_const(2), register(1,8)) + MOV_mr = insn(rex_w, '\x89', mem_reg_plus_const(1), register(2,8)) + MOV_mi = insn(rex_w, '\xC7', mem_reg_plus_const(1), orbyte(0<<3), + immediate(2, 'i')) # "MOV reg1, [reg2+reg3*scale+offset]" and the opposite direction - MOV_ra = insn(rex_w, '\x8B', register(1,8), - mem_reg_plus_scaled_reg_plus_const(2)) - MOV_ar = insn(rex_w, '\x89', register(2,8), - mem_reg_plus_scaled_reg_plus_const(1)) + MOV_ra = insn(rex_w, '\x8B', mem_reg_plus_scaled_reg_plus_const(2), + register(1,8)) + MOV_ar = insn(rex_w, '\x89', mem_reg_plus_scaled_reg_plus_const(1), + register(2,8)) # "MOV reg1, [immediate2]" and the opposite direction - MOV_rj = insn(rex_w, '\x8B', register(1,8), '\x05', immediate(2)) - MOV_jr = insn(rex_w, '\x89', register(2,8), '\x05', immediate(1)) + MOV_rj = insn(rex_w, '\x8B', '\x05', register(1,8), immediate(2)) + MOV_jr = insn(rex_w, '\x89', '\x05', register(2,8), immediate(1)) # ------------------------------ Arithmetic ------------------------------ @@ -370,34 +368,33 @@ NOP = insn('\x90') RET = insn('\xC3') - PUSH_r = insn(rex_nw, register(1), '\x50') - POP_r = insn(rex_nw, register(1), '\x58') + PUSH_r = insn(rex_nw, '\x50', register(1)) + POP_r = insn(rex_nw, '\x58', register(1)) - LEA_rb = insn(rex_w, '\x8D', register(1,8), stack_bp(2)) - LEA32_rb = insn(rex_w, '\x8D', register(1,8),stack_bp(2,force_32bits=True)) + LEA_rb = insn(rex_w, '\x8D', stack_bp(2), register(1,8)) + LEA32_rb = insn(rex_w, '\x8D', stack_bp(2,force_32bits=True),register(1,8)) CALL_l = insn('\xE8', relative(1)) - CALL_r = insn(rex_nw, '\xFF', register(1), chr(0xC0 | (2<<3))) - CALL_b = insn('\xFF', orbyte(2<<3), stack_bp(1)) + CALL_r = insn(rex_nw, '\xFF', chr(0xC0 | (2<<3)), register(1)) + CALL_b = insn('\xFF', stack_bp(1), orbyte(2<<3)) - XCHG_rm = insn(rex_w, '\x87', register(1,8), mem_reg_plus_const(2)) + XCHG_rm = insn(rex_w, '\x87', mem_reg_plus_const(2), register(1,8)) JMP_l = insn('\xE9', relative(1)) - J_il = insn('\x0F', immediate(1,'o'), '\x80', relative(2)) - SET_ir = insn('\x0F', immediate(1,'o'),'\x90', register(2), '\xC0') + J_il = insn('\x0F\x80', immediate(1,'o'), relative(2)) + SET_ir = insn('\x0F\x90', immediate(1,'o'), '\xC0', register(2)) # ------------------------------ SSE2 ------------------------------ - MOVSD_rr = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), register(2), - '\xC0') - MOVSD_rb = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), stack_bp(2)) - MOVSD_br = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), stack_bp(1)) - MOVSD_rs = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), stack_sp(2)) - MOVSD_sr = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), stack_sp(1)) - MOVSD_rm = xmminsn('\xF2', rex_nw, '\x0F\x10', register(1,8), - mem_reg_plus_const(2)) - MOVSD_mr = xmminsn('\xF2', rex_nw, '\x0F\x11', register(2,8), - mem_reg_plus_const(1)) + MOVSD_rr = xmminsn('\xF2', rex_nw,'\x0F\x10\xC0',register(1,8),register(2)) + MOVSD_rb = xmminsn('\xF2', rex_nw, '\x0F\x10', stack_bp(2), register(1,8)) + MOVSD_br = xmminsn('\xF2', rex_nw, '\x0F\x11', stack_bp(1), register(2,8)) + MOVSD_rs = xmminsn('\xF2', rex_nw, '\x0F\x10', stack_sp(2), register(1,8)) + MOVSD_sr = xmminsn('\xF2', rex_nw, '\x0F\x11', stack_sp(1), register(2,8)) + MOVSD_rm = xmminsn('\xF2', rex_nw, '\x0F\x10', mem_reg_plus_const(2), + register(1,8)) + MOVSD_mr = xmminsn('\xF2', rex_nw, '\x0F\x11', mem_reg_plus_const(1), + register(2,8)) # ------------------------------------------------------------ @@ -429,18 +426,18 @@ WORD = 8 def writeimm64(self, imm): - self.writechar(chr(imm & 0xFF)) - self.writechar(chr((imm >> 8) & 0xFF)) - self.writechar(chr((imm >> 16) & 0xFF)) - self.writechar(chr((imm >> 24) & 0xFF)) - self.writechar(chr((imm >> 32) & 0xFF)) - self.writechar(chr((imm >> 40) & 0xFF)) - self.writechar(chr((imm >> 48) & 0xFF)) self.writechar(chr((imm >> 56) & 0xFF)) + self.writechar(chr((imm >> 48) & 0xFF)) + self.writechar(chr((imm >> 40) & 0xFF)) + self.writechar(chr((imm >> 32) & 0xFF)) + self.writechar(chr((imm >> 24) & 0xFF)) + self.writechar(chr((imm >> 16) & 0xFF)) + self.writechar(chr((imm >> 8) & 0xFF)) + self.writechar(chr(imm & 0xFF)) # MOV_ri from the parent class is not wrong, but here is a better encoding # for the common case where the immediate fits in 32 bits - _MOV_ri32 = insn(rex_w, '\xC7', register(1), '\xC0', immediate(2, 'i')) + _MOV_ri32 = insn(rex_w, '\xC7\xC0', register(1), immediate(2, 'i')) def MOV_ri(self, reg, immed): if fits_in_32bits(immed): @@ -455,8 +452,8 @@ if fits_in_32bits(offset): AbstractX86CodeBuilder.CALL_l(self, target) else: - AbstractX86CodeBuilder.MOV_ri(self, R.eax, target) AbstractX86CodeBuilder.CALL_r(self, R.eax) + AbstractX86CodeBuilder.MOV_ri(self, R.eax, target) # unsupported -- must use e.g. MOV tmpreg, immed64; MOV reg, [tmpreg] def MOV_rj(self, reg, mem_immed): Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/__init__.py ============================================================================== Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_runner.py ============================================================================== --- (empty file) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_runner.py Sat Mar 13 16:56:03 2010 @@ -0,0 +1,16 @@ +import py +from pypy.jit.backend.newx86.runner import CPU +from pypy.jit.backend.test.runner_test import LLtypeBackendTest + +class FakeStats(object): + pass + +# ____________________________________________________________ + +class TestX86(LLtypeBackendTest): + + # for the individual tests see + # ====> ../../test/runner_test.py + + def setup_method(self, meth): + self.cpu = CPU(rtyper=None, stats=FakeStats()) Copied: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_rx86.py (from r72201, pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/test/test_rx86.py) ============================================================================== --- pypy/branch/remove-ri386-multimethod-2/pypy/jit/backend/x86/test/test_rx86.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_rx86.py Sat Mar 13 16:56:03 2010 @@ -1,5 +1,5 @@ import py, struct -from pypy.jit.backend.x86.rx86 import * +from pypy.jit.backend.newx86.rx86 import * globals().update(R.__dict__) class CodeBuilderMixin(object): @@ -11,10 +11,11 @@ self.buffer.append(c) # append a character def getvalue(self): - return ''.join(self.buffer) + buf = self.buffer[::-1] + return ''.join(buf) def tell(self): - return 0x76543210 + len(self.buffer) + return 0x76543210 - len(self.buffer) class CodeBuilder32(CodeBuilderMixin, X86_32_CodeBuilder): @@ -42,40 +43,40 @@ def test_mov_rm(): s = CodeBuilder32() - s.MOV_rm(edx, (edi, 0)) - s.MOV_rm(edx, (edi, -128)) s.MOV_rm(edx, (edi, 128)) + s.MOV_rm(edx, (edi, -128)) + s.MOV_rm(edx, (edi, 0)) assert s.getvalue() == '\x8B\x17\x8B\x57\x80\x8B\x97\x80\x00\x00\x00' def test_mov_mr(): s = CodeBuilder32() - s.MOV_mr((edi, 0), edx) - s.MOV_mr((edi, -128), edx) s.MOV_mr((edi, 128), edx) + s.MOV_mr((edi, -128), edx) + s.MOV_mr((edi, 0), edx) assert s.getvalue() == '\x89\x17\x89\x57\x80\x89\x97\x80\x00\x00\x00' def test_mov_ra(): s = CodeBuilder32() - s.MOV_ra(edx, (esi, edi, 2, 0)) - s.MOV_ra(edx, (esi, edi, 2, -128)) s.MOV_ra(edx, (esi, edi, 2, 128)) + s.MOV_ra(edx, (esi, edi, 2, -128)) + s.MOV_ra(edx, (esi, edi, 2, 0)) assert s.getvalue() == ('\x8B\x14\xBE' + '\x8B\x54\xBE\x80' + '\x8B\x94\xBE\x80\x00\x00\x00') def test_mov_ar(): s = CodeBuilder32() - s.MOV_ar((esi, edi, 2, 0), edx) - s.MOV_ar((esi, edi, 2, -128), edx) s.MOV_ar((esi, edi, 2, 128), edx) + s.MOV_ar((esi, edi, 2, -128), edx) + s.MOV_ar((esi, edi, 2, 0), edx) assert s.getvalue() == ('\x89\x14\xBE' + '\x89\x54\xBE\x80' + '\x89\x94\xBE\x80\x00\x00\x00') def test_nop_add_rr(): s = CodeBuilder32() - s.NOP() s.ADD_rr(eax, eax) + s.NOP() assert s.getvalue() == '\x90\x01\xC0' def test_lea_rb(): @@ -91,19 +92,19 @@ def test_call_l(s=None): s = s or CodeBuilder32() s.CALL_l(0x01234567) - ofs = 0x01234567 - (0x76543210+5) + ofs = 0x01234567 - 0x76543210 assert s.getvalue() == '\xE8' + struct.pack(" Author: benjamin Date: Sat Mar 13 18:29:03 2010 New Revision: 72203 Modified: pypy/trunk/pypy/objspace/std/stringobject.py Log: remove the __iter__ method, since it's pointless Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Sat Mar 13 18:29:03 2010 @@ -871,10 +871,6 @@ return w_str return wrapstr(space, w_str._value) -def iter__String(space, w_list): - from pypy.objspace.std import iterobject - return iterobject.W_SeqIterObject(w_list) - def ord__String(space, w_str): u_str = w_str._value if len(u_str) != 1: From xoraxax at codespeak.net Sat Mar 13 18:43:04 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 13 Mar 2010 18:43:04 +0100 (CET) Subject: [pypy-svn] r72204 - pypy/benchmarks Message-ID: <20100313174304.3BB22282BF2@codespeak.net> Author: xoraxax Date: Sat Mar 13 18:43:02 2010 New Revision: 72204 Modified: pypy/benchmarks/runner.py Log: Try with default optionname. Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Sat Mar 13 18:43:02 2010 @@ -41,7 +41,7 @@ optionsname = "gc=hybrid" if "psyco.sh" in pypy_c_path: name = "python-psyco-profile" - optionsname = "" + optionsname = "default" if force_host is not None: host = force_host else: From xoraxax at codespeak.net Sat Mar 13 19:04:53 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 13 Mar 2010 19:04:53 +0100 (CET) Subject: [pypy-svn] r72205 - pypy/build/bot2/pypybuildbot Message-ID: <20100313180453.DB4F7282BF2@codespeak.net> Author: xoraxax Date: Sat Mar 13 19:04:52 2010 New Revision: 72205 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Move Psyco step to the beginning. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Mar 13 19:04:52 2010 @@ -127,6 +127,18 @@ command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', 'benchmarks'], workdir='.')) + + self.addStep(ShellCmd( + description="run benchmarks on top of python with psyco", + command=["python", "runner.py", '--output-filename', 'result.json', + '--pypy-c', 'psyco/python_with_psyco.sh', + '--revision', WithProperties('%(got_revision)s'), + '--upload', '--force-host', 'bigdog', + '--branch', WithProperties('%(branch)s'), + ], + workdir='./benchmarks', + haltOnFailure=True)) + self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks on top of pypy-c-jit", @@ -157,16 +169,7 @@ masterdest=WithProperties(resfile), workdir=".")) - self.addStep(ShellCmd( - description="run benchmarks on top of python with psyco", - command=["python", "runner.py", '--output-filename', 'result.json', - '--pypy-c', 'psyco/python_with_psyco.sh', - '--revision', WithProperties('%(got_revision)s'), - '--upload', '--force-host', 'bigdog', - '--branch', WithProperties('%(branch)s'), - ], - workdir='./benchmarks', - haltOnFailure=True)) + self.addStep(ShellCmd( description="run benchmarks 1", From fijal at codespeak.net Sat Mar 13 19:16:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 13 Mar 2010 19:16:52 +0100 (CET) Subject: [pypy-svn] r72206 - in pypy/trunk/pypy/module/imp: . test Message-ID: <20100313181652.416C6282BF2@codespeak.net> Author: fijal Date: Sat Mar 13 19:16:50 2010 New Revision: 72206 Modified: pypy/trunk/pypy/module/imp/importing.py pypy/trunk/pypy/module/imp/interp_imp.py pypy/trunk/pypy/module/imp/test/test_app.py Log: A test (and a fix?). I think the only other guy who might be confused now is reload() but we have no tests that break (at the very least) Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Sat Mar 13 19:16:50 2010 @@ -356,9 +356,14 @@ return space.getbuiltinmodule(find_info.filename, force_init=True) if find_info.modtype in (PY_SOURCE, PY_COMPILED, PKG_DIRECTORY): + w_mod = None if reuse: - w_mod = space.getitem(space.sys.get('modules'), w_modulename) - else: + try: + w_mod = space.getitem(space.sys.get('modules'), w_modulename) + except OperationError, oe: + if not oe.match(space, space.w_KeyError): + raise + if w_mod is None: w_mod = space.wrap(Module(space, w_modulename)) if find_info.modtype == PKG_DIRECTORY: pkgdir = find_info.filename Modified: pypy/trunk/pypy/module/imp/interp_imp.py ============================================================================== --- pypy/trunk/pypy/module/imp/interp_imp.py (original) +++ pypy/trunk/pypy/module/imp/interp_imp.py Sat Mar 13 19:16:50 2010 @@ -76,7 +76,7 @@ space.str_w(w_suffix), filemode) return importing.load_module( - space, w_name, find_info) + space, w_name, find_info, reuse=True) def load_source(space, w_modulename, w_filename, w_file=None): filename = space.str_w(w_filename) Modified: pypy/trunk/pypy/module/imp/test/test_app.py ============================================================================== --- pypy/trunk/pypy/module/imp/test/test_app.py (original) +++ pypy/trunk/pypy/module/imp/test/test_app.py Sat Mar 13 19:16:50 2010 @@ -110,3 +110,14 @@ pass else: raise Exception("expected an ImportError") + + def test_load_module_in_sys_modules(self): + fn = self._py_file() + f = open(fn, 'rb') + descr = ('.py', 'U', self.imp.PY_SOURCE) + mod = self.imp.load_module('test_imp_extra_AUTO6', f, fn, descr) + f.close() + f = open(fn, 'rb') + mod2 = self.imp.load_module('test_imp_extra_AUTO6', f, fn, descr) + f.close() + assert mod2 is mod From xoraxax at codespeak.net Sat Mar 13 20:47:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 13 Mar 2010 20:47:49 +0100 (CET) Subject: [pypy-svn] r72207 - pypy/build/bot2/pypybuildbot Message-ID: <20100313194749.6AF0F282BF2@codespeak.net> Author: xoraxax Date: Sat Mar 13 20:47:47 2010 New Revision: 72207 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Move psyco back to the end, svn merge -r 72205:72186 builds.py Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Sat Mar 13 20:47:47 2010 @@ -127,18 +127,6 @@ command=['svn', 'co', 'http://codespeak.net/svn/pypy/benchmarks', 'benchmarks'], workdir='.')) - - self.addStep(ShellCmd( - description="run benchmarks on top of python with psyco", - command=["python", "runner.py", '--output-filename', 'result.json', - '--pypy-c', 'psyco/python_with_psyco.sh', - '--revision', WithProperties('%(got_revision)s'), - '--upload', '--force-host', 'bigdog', - '--branch', WithProperties('%(branch)s'), - ], - workdir='./benchmarks', - haltOnFailure=True)) - self.addStep(Translate(['-Ojit'], [])) self.addStep(ShellCmd( description="run more benchmarks on top of pypy-c-jit", @@ -169,7 +157,16 @@ masterdest=WithProperties(resfile), workdir=".")) - + self.addStep(ShellCmd( + description="run benchmarks on top of python with psyco", + command=["python", "runner.py", '--output-filename', 'result.json', + '--pypy-c', 'psyco/python_with_psyco.sh', + '--revision', WithProperties('%(got_revision)s'), + '--upload', '--force-host', 'bigdog', + '--branch', WithProperties('%(branch)s'), + ], + workdir='./benchmarks', + haltOnFailure=True)) self.addStep(ShellCmd( description="run benchmarks 1", From benjamin at codespeak.net Sat Mar 13 21:25:36 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sat, 13 Mar 2010 21:25:36 +0100 (CET) Subject: [pypy-svn] r72208 - pypy/trunk/pypy/translator/c/src Message-ID: <20100313202536.C03BC282BF2@codespeak.net> Author: benjamin Date: Sat Mar 13 21:25:34 2010 New Revision: 72208 Modified: pypy/trunk/pypy/translator/c/src/signals.h Log: fix indentation 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 Sat Mar 13 21:25:34 2010 @@ -102,7 +102,7 @@ context.sa_flags = 0; sigaction(signum, &context, NULL); #else - signal(signum, SIG_IGN); + signal(signum, SIG_IGN); #endif } @@ -116,17 +116,17 @@ context.sa_flags = 0; sigaction(signum, &context, NULL); #else - signal(signum, SIG_DFL); + signal(signum, SIG_DFL); #endif } static void signal_setflag_handler(int signum) { - if (0 <= signum && signum < NSIG) - pypysig_flags[signum] = 1; - /* the point of "*pypysig_occurred_v" instead of just "pypysig_occurred" - is the volatile declaration */ - *pypysig_occurred_v |= PENDING_SIGNAL_BIT; + if (0 <= signum && signum < NSIG) + pypysig_flags[signum] = 1; + /* the point of "*pypysig_occurred_v" instead of just "pypysig_occurred" + is the volatile declaration */ + *pypysig_occurred_v |= PENDING_SIGNAL_BIT; } void pypysig_setflag(int signum) @@ -139,7 +139,7 @@ context.sa_flags = 0; sigaction(signum, &context, NULL); #else - signal(signum, signal_setflag_handler); + signal(signum, signal_setflag_handler); #endif } @@ -152,18 +152,18 @@ /* if (pypysig_occurred & PENDING_SIGNAL_BIT) */ { - int i; + int i; /* pypysig_occurred &= ~PENDING_SIGNAL_BIT; */ - for (i=0; i Author: fijal Date: Sat Mar 13 23:04:54 2010 New Revision: 72210 Added: pypy/branch/arraycopy/ - copied from r72209, pypy/trunk/ Log: A branch on which I would try to make jit arraycopy-aware From fijal at codespeak.net Sun Mar 14 01:10:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 01:10:06 +0100 (CET) Subject: [pypy-svn] r72211 - in pypy/branch/arraycopy/pypy: jit/backend jit/backend/llgraph jit/metainterp jit/metainterp/test rlib Message-ID: <20100314001006.5E5C8282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 01:10:04 2010 New Revision: 72211 Modified: pypy/branch/arraycopy/pypy/jit/backend/llgraph/runner.py pypy/branch/arraycopy/pypy/jit/backend/model.py pypy/branch/arraycopy/pypy/jit/metainterp/codewriter.py pypy/branch/arraycopy/pypy/jit/metainterp/optimizeopt.py pypy/branch/arraycopy/pypy/jit/metainterp/pyjitpl.py pypy/branch/arraycopy/pypy/jit/metainterp/resoperation.py pypy/branch/arraycopy/pypy/jit/metainterp/simple_optimize.py pypy/branch/arraycopy/pypy/jit/metainterp/support.py pypy/branch/arraycopy/pypy/jit/metainterp/test/test_codewriter.py pypy/branch/arraycopy/pypy/jit/metainterp/test/test_list.py pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py pypy/branch/arraycopy/pypy/rlib/rgc.py Log: A first part of arraycopy optimizations Modified: pypy/branch/arraycopy/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/branch/arraycopy/pypy/jit/backend/llgraph/runner.py Sun Mar 14 01:10:04 2010 @@ -15,6 +15,7 @@ from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic from pypy.jit.metainterp.typesystem import llhelper, oohelper +from pypy.rlib import rgc class MiniStats: pass Modified: pypy/branch/arraycopy/pypy/jit/backend/model.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/backend/model.py (original) +++ pypy/branch/arraycopy/pypy/jit/backend/model.py Sun Mar 14 01:10:04 2010 @@ -175,6 +175,11 @@ def do_getarrayitem_gc(self, arraybox, indexbox, arraydescr): raise NotImplementedError + + def do_arraycopy(self, calldescr, fnptr, sourcebox, destbox, + source_startbox, dest_startbox, lengthbox, arraydescr): + return self.do_call([fnptr, sourcebox, destbox, source_startbox, + dest_startbox, lengthbox], calldescr) def do_getfield_gc(self, structbox, fielddescr): raise NotImplementedError Modified: pypy/branch/arraycopy/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/codewriter.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/codewriter.py Sun Mar 14 01:10:04 2010 @@ -1452,6 +1452,8 @@ self.register_var(op.result) return True # + if oopspec_name == 'list.ll_arraycopy': + return self.handle_arraycopy(op, arraydescr, args) if oopspec_name == 'list.getitem': return self.handle_list_getitem(op, arraydescr, args, 'getarrayitem_gc') @@ -1534,6 +1536,18 @@ self.register_var(op.result) return True + def handle_arraycopy(self, op, arraydescr, args): + self.emit('arraycopy') + calldescr, _ = self.codewriter.getcalldescr(op.args[0], args, op.result, + consider_effects_of=op) + self.emit(self.get_position(calldescr)) + self.emit(self.var_position(op.args[0])) + for arg in args: + self.emit(self.var_position(arg)) + self.emit(self.get_position(arraydescr)) + self.register_var(op.result) + return True + def prepare_list_getset(self, op, descr, args, checkname): if op.opname == 'oosend': SELFTYPE, _, meth = support.lookup_oosend_method(op) Modified: pypy/branch/arraycopy/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/optimizeopt.py Sun Mar 14 01:10:04 2010 @@ -16,6 +16,7 @@ from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype +from pypy.jit.metainterp.history import AbstractDescr def optimize_loop_1(metainterp_sd, loop): """Optimize loop.operations to make it match the input of loop.specnodes @@ -910,6 +911,27 @@ fieldvalue = self.getvalue(op.args[2]) self.heap_op_optimizer.optimize_SETARRAYITEM_GC(op, value, fieldvalue) + def optimize_ARRAYCOPY(self, op): + source_value = self.getvalue(op.args[2]) + dest_value = self.getvalue(op.args[3]) + source_start_box = self.get_constant_box(op.args[4]) + dest_start_box = self.get_constant_box(op.args[5]) + length = self.get_constant_box(op.args[6]) + if (source_value.is_virtual() and source_start_box and dest_start_box + and length and dest_value.is_virtual()): + # XXX optimize the case where dest value is not virtual, + # but we still can avoid a mess + source_start = source_start_box.getint() + dest_start = dest_start_box.getint() + for index in range(length.getint()): + val = source_value.getitem(index + source_start) + dest_value.setitem(index + dest_start, val) + return + descr = op.args[0] + assert isinstance(descr, AbstractDescr) + self.emit_operation(ResOperation(rop.CALL, op.args[1:], op.result, + descr)) + def optimize_INSTANCEOF(self, op): value = self.getvalue(op.args[0]) realclassbox = value.get_constant_class(self.cpu) Modified: pypy/branch/arraycopy/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/pyjitpl.py Sun Mar 14 01:10:04 2010 @@ -360,6 +360,13 @@ def opimpl_arraylen_gc(self, arraybox, arraydesc): self.execute_with_descr(rop.ARRAYLEN_GC, arraydesc, arraybox) + @arguments("descr", "box", "box", "box", "box", "box", "box", "descr") + def opimpl_arraycopy(self, calldescr, fnptr, sourcebox, destbox, + source_startbox, dest_startbox, lengthbox, arraydescr): + self.execute_with_descr(rop.ARRAYCOPY, arraydescr, calldescr, fnptr, + sourcebox, destbox, source_startbox, + dest_startbox, lengthbox) + @arguments("orgpc", "box", "descr", "box") def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox): negbox = self.metainterp.execute_and_record( Modified: pypy/branch/arraycopy/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/resoperation.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/resoperation.py Sun Mar 14 01:10:04 2010 @@ -216,6 +216,7 @@ 'SETARRAYITEM_RAW/3d',#only added by backend.llsupport.gc.rewrite_assembler 'SETFIELD_GC/2d', 'SETFIELD_RAW/2d', + 'ARRAYCOPY/7d', 'NEWSTR/1', 'STRSETITEM/3', 'UNICODESETITEM/3', Modified: pypy/branch/arraycopy/pypy/jit/metainterp/simple_optimize.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/simple_optimize.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/simple_optimize.py Sun Mar 14 01:10:04 2010 @@ -2,11 +2,21 @@ """ Simplified optimize.py """ -from pypy.jit.metainterp.resoperation import rop +from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp import resume, compile EMPTY_VALUES = {} +def transform(op): + from pypy.jit.metainterp.history import AbstractDescr + # change ARRAYCOPY to call, so we don't have to pass around + # unnecessary information to the backend + if op.opnum == rop.ARRAYCOPY: + descr = op.args[0] + assert isinstance(descr, AbstractDescr) + return ResOperation(rop.CALL, op.args[1:], op.result, descr=descr) + return op + def optimize_loop(metainterp_sd, old_loops, loop): if old_loops: assert len(old_loops) == 1 @@ -25,7 +35,7 @@ modifier = resume.ResumeDataVirtualAdder(descr, memo) newboxes = modifier.finish(EMPTY_VALUES) descr.store_final_boxes(op, newboxes) - newoperations.append(op) + newoperations.append(transform(op)) loop.operations = newoperations return None Modified: pypy/branch/arraycopy/pypy/jit/metainterp/support.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/support.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/support.py Sun Mar 14 01:10:04 2010 @@ -17,6 +17,7 @@ from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.rpython.extregistry import ExtRegistryEntry from pypy.jit.metainterp.typesystem import deref +from pypy.rlib import rgc def getargtypes(annotator, values): if values is None: # for backend tests producing stand-alone exe's @@ -134,6 +135,8 @@ _ll_2_list_getitem_foldable = _ll_2_list_getitem _ll_1_list_len_foldable = _ll_1_list_len +_ll_5_list_ll_arraycopy = rgc.ll_arraycopy + def _ll_1_gc_identityhash(x): return lltype.identityhash(x) Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_codewriter.py Sun Mar 14 01:10:04 2010 @@ -150,6 +150,8 @@ return ('typedescr', CLASS) def methdescrof(self, CLASS, methname): return FakeMethDescr(CLASS, methname) + def arraydescrof(self, ARRAY): + return ('arraydescr', ARRAY) def sizeof(self, STRUCT): return ('sizeof', STRUCT) @@ -512,6 +514,28 @@ assert ConstInt(55) in jitcode.constants assert ConstInt(66) not in jitcode.constants + def test_ll_arraycopy(self): + from pypy.rlib import rgc + from pypy.rpython.lltypesystem import lltype + + A = lltype.GcArray(lltype.Signed) + + def f(): + l = lltype.malloc(A, 3) + l[0] = 1 + l[1] = 2 + l[3] = 3 + l2 = lltype.malloc(A, 3) + rgc.ll_arraycopy(l, l2, 0, 0, 3) + return l2[0] + l2[1] + l2[3] + + graphs = self.make_graphs(f, []) + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'residual_call' not in jitcode._source + assert 'arraycopy' in jitcode._source class ImmutableFieldsTests: Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_list.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_list.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_list.py Sun Mar 14 01:10:04 2010 @@ -118,6 +118,32 @@ assert res == f(10) py.test.skip("'[non-null] * n' gives a residual call so far") self.check_loops(setarrayitem_gc=0, getarrayitem_gc=0, call=0) + + def test_arraycopy_simpleoptimize(self): + def f(): + l = [1, 2, 3, 4] + l2 = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == 10 + + def test_arraycopy_full(self): + jitdriver = JitDriver(greens = [], reds = ['n']) + def f(n): + l = [] + l2 = [] + while n > 0: + jitdriver.can_enter_jit(n=n) + jitdriver.jit_merge_point(n=n) + l = [1, 2, 3, n] + l2 = l[:] + n -= 1 + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.meta_interp(f, [5], listops=True) + assert res == 7 + self.check_loops(call=0) class TestOOtype(ListTests, OOJitMixin): pass Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 01:10:04 2010 @@ -2723,6 +2723,8 @@ """ self.optimize_loop(ops, 'Not, Not', expected) + def test_arraycopy_1(self): + class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): Modified: pypy/branch/arraycopy/pypy/rlib/rgc.py ============================================================================== --- pypy/branch/arraycopy/pypy/rlib/rgc.py (original) +++ pypy/branch/arraycopy/pypy/rlib/rgc.py Sun Mar 14 01:10:04 2010 @@ -276,7 +276,7 @@ keepalive_until_here(dest) ll_arraycopy._annenforceargs_ = [None, None, int, int, int] ll_arraycopy._annspecialcase_ = 'specialize:ll' -ll_arraycopy._jit_look_inside_ = False +ll_arraycopy.oopspec = 'list.ll_arraycopy(source, dest, source_start, dest_start, length)' def ll_shrink_array(p, smallerlength): from pypy.rpython.lltypesystem.lloperation import llop @@ -310,7 +310,6 @@ ll_shrink_array._annspecialcase_ = 'specialize:ll' ll_shrink_array._jit_look_inside_ = False - def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True From fijal at codespeak.net Sun Mar 14 01:11:56 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 01:11:56 +0100 (CET) Subject: [pypy-svn] r72212 - pypy/branch/arraycopy/pypy/jit/metainterp/test Message-ID: <20100314001156.401CC282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 01:11:54 2010 New Revision: 72212 Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Log: Fix syntax error Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 01:11:54 2010 @@ -2724,7 +2724,7 @@ self.optimize_loop(ops, 'Not, Not', expected) def test_arraycopy_1(self): - + pass class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): From fijal at codespeak.net Sun Mar 14 01:13:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 01:13:15 +0100 (CET) Subject: [pypy-svn] r72213 - in pypy/trunk/pypy: jit/backend jit/backend/llgraph jit/metainterp jit/metainterp/test rlib Message-ID: <20100314001315.350B0282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 01:13:13 2010 New Revision: 72213 Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py pypy/trunk/pypy/jit/backend/model.py pypy/trunk/pypy/jit/metainterp/codewriter.py pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/pyjitpl.py pypy/trunk/pypy/jit/metainterp/resoperation.py pypy/trunk/pypy/jit/metainterp/simple_optimize.py pypy/trunk/pypy/jit/metainterp/support.py pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py pypy/trunk/pypy/jit/metainterp/test/test_list.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py pypy/trunk/pypy/rlib/rgc.py Log: Merge arraycopy branch, part of it. It's the simplest way to run benchmarks until we have per-branch run Modified: pypy/trunk/pypy/jit/backend/llgraph/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llgraph/runner.py (original) +++ pypy/trunk/pypy/jit/backend/llgraph/runner.py Sun Mar 14 01:13:13 2010 @@ -15,6 +15,7 @@ from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic from pypy.jit.metainterp.typesystem import llhelper, oohelper +from pypy.rlib import rgc class MiniStats: pass Modified: pypy/trunk/pypy/jit/backend/model.py ============================================================================== --- pypy/trunk/pypy/jit/backend/model.py (original) +++ pypy/trunk/pypy/jit/backend/model.py Sun Mar 14 01:13:13 2010 @@ -175,6 +175,11 @@ def do_getarrayitem_gc(self, arraybox, indexbox, arraydescr): raise NotImplementedError + + def do_arraycopy(self, calldescr, fnptr, sourcebox, destbox, + source_startbox, dest_startbox, lengthbox, arraydescr): + return self.do_call([fnptr, sourcebox, destbox, source_startbox, + dest_startbox, lengthbox], calldescr) def do_getfield_gc(self, structbox, fielddescr): raise NotImplementedError Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Sun Mar 14 01:13:13 2010 @@ -1452,6 +1452,8 @@ self.register_var(op.result) return True # + if oopspec_name == 'list.ll_arraycopy': + return self.handle_arraycopy(op, arraydescr, args) if oopspec_name == 'list.getitem': return self.handle_list_getitem(op, arraydescr, args, 'getarrayitem_gc') @@ -1534,6 +1536,18 @@ self.register_var(op.result) return True + def handle_arraycopy(self, op, arraydescr, args): + self.emit('arraycopy') + calldescr, _ = self.codewriter.getcalldescr(op.args[0], args, op.result, + consider_effects_of=op) + self.emit(self.get_position(calldescr)) + self.emit(self.var_position(op.args[0])) + for arg in args: + self.emit(self.var_position(arg)) + self.emit(self.get_position(arraydescr)) + self.register_var(op.result) + return True + def prepare_list_getset(self, op, descr, args, checkname): if op.opname == 'oosend': SELFTYPE, _, meth = support.lookup_oosend_method(op) Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Sun Mar 14 01:13:13 2010 @@ -16,6 +16,7 @@ from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype +from pypy.jit.metainterp.history import AbstractDescr def optimize_loop_1(metainterp_sd, loop): """Optimize loop.operations to make it match the input of loop.specnodes @@ -910,6 +911,27 @@ fieldvalue = self.getvalue(op.args[2]) self.heap_op_optimizer.optimize_SETARRAYITEM_GC(op, value, fieldvalue) + def optimize_ARRAYCOPY(self, op): + source_value = self.getvalue(op.args[2]) + dest_value = self.getvalue(op.args[3]) + source_start_box = self.get_constant_box(op.args[4]) + dest_start_box = self.get_constant_box(op.args[5]) + length = self.get_constant_box(op.args[6]) + if (source_value.is_virtual() and source_start_box and dest_start_box + and length and dest_value.is_virtual()): + # XXX optimize the case where dest value is not virtual, + # but we still can avoid a mess + source_start = source_start_box.getint() + dest_start = dest_start_box.getint() + for index in range(length.getint()): + val = source_value.getitem(index + source_start) + dest_value.setitem(index + dest_start, val) + return + descr = op.args[0] + assert isinstance(descr, AbstractDescr) + self.emit_operation(ResOperation(rop.CALL, op.args[1:], op.result, + descr)) + def optimize_INSTANCEOF(self, op): value = self.getvalue(op.args[0]) realclassbox = value.get_constant_class(self.cpu) Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original) +++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Sun Mar 14 01:13:13 2010 @@ -360,6 +360,13 @@ def opimpl_arraylen_gc(self, arraybox, arraydesc): self.execute_with_descr(rop.ARRAYLEN_GC, arraydesc, arraybox) + @arguments("descr", "box", "box", "box", "box", "box", "box", "descr") + def opimpl_arraycopy(self, calldescr, fnptr, sourcebox, destbox, + source_startbox, dest_startbox, lengthbox, arraydescr): + self.execute_with_descr(rop.ARRAYCOPY, arraydescr, calldescr, fnptr, + sourcebox, destbox, source_startbox, + dest_startbox, lengthbox) + @arguments("orgpc", "box", "descr", "box") def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox): negbox = self.metainterp.execute_and_record( Modified: pypy/trunk/pypy/jit/metainterp/resoperation.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/resoperation.py (original) +++ pypy/trunk/pypy/jit/metainterp/resoperation.py Sun Mar 14 01:13:13 2010 @@ -216,6 +216,7 @@ 'SETARRAYITEM_RAW/3d',#only added by backend.llsupport.gc.rewrite_assembler 'SETFIELD_GC/2d', 'SETFIELD_RAW/2d', + 'ARRAYCOPY/7d', 'NEWSTR/1', 'STRSETITEM/3', 'UNICODESETITEM/3', Modified: pypy/trunk/pypy/jit/metainterp/simple_optimize.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/simple_optimize.py (original) +++ pypy/trunk/pypy/jit/metainterp/simple_optimize.py Sun Mar 14 01:13:13 2010 @@ -2,11 +2,21 @@ """ Simplified optimize.py """ -from pypy.jit.metainterp.resoperation import rop +from pypy.jit.metainterp.resoperation import rop, ResOperation from pypy.jit.metainterp import resume, compile EMPTY_VALUES = {} +def transform(op): + from pypy.jit.metainterp.history import AbstractDescr + # change ARRAYCOPY to call, so we don't have to pass around + # unnecessary information to the backend + if op.opnum == rop.ARRAYCOPY: + descr = op.args[0] + assert isinstance(descr, AbstractDescr) + return ResOperation(rop.CALL, op.args[1:], op.result, descr=descr) + return op + def optimize_loop(metainterp_sd, old_loops, loop): if old_loops: assert len(old_loops) == 1 @@ -25,7 +35,7 @@ modifier = resume.ResumeDataVirtualAdder(descr, memo) newboxes = modifier.finish(EMPTY_VALUES) descr.store_final_boxes(op, newboxes) - newoperations.append(op) + newoperations.append(transform(op)) loop.operations = newoperations return None Modified: pypy/trunk/pypy/jit/metainterp/support.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/support.py (original) +++ pypy/trunk/pypy/jit/metainterp/support.py Sun Mar 14 01:13:13 2010 @@ -17,6 +17,7 @@ from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.rpython.extregistry import ExtRegistryEntry from pypy.jit.metainterp.typesystem import deref +from pypy.rlib import rgc def getargtypes(annotator, values): if values is None: # for backend tests producing stand-alone exe's @@ -134,6 +135,8 @@ _ll_2_list_getitem_foldable = _ll_2_list_getitem _ll_1_list_len_foldable = _ll_1_list_len +_ll_5_list_ll_arraycopy = rgc.ll_arraycopy + def _ll_1_gc_identityhash(x): return lltype.identityhash(x) Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Sun Mar 14 01:13:13 2010 @@ -150,6 +150,8 @@ return ('typedescr', CLASS) def methdescrof(self, CLASS, methname): return FakeMethDescr(CLASS, methname) + def arraydescrof(self, ARRAY): + return ('arraydescr', ARRAY) def sizeof(self, STRUCT): return ('sizeof', STRUCT) @@ -512,6 +514,28 @@ assert ConstInt(55) in jitcode.constants assert ConstInt(66) not in jitcode.constants + def test_ll_arraycopy(self): + from pypy.rlib import rgc + from pypy.rpython.lltypesystem import lltype + + A = lltype.GcArray(lltype.Signed) + + def f(): + l = lltype.malloc(A, 3) + l[0] = 1 + l[1] = 2 + l[3] = 3 + l2 = lltype.malloc(A, 3) + rgc.ll_arraycopy(l, l2, 0, 0, 3) + return l2[0] + l2[1] + l2[3] + + graphs = self.make_graphs(f, []) + cw = CodeWriter(self.rtyper) + cw.candidate_graphs = [graphs[0]] + cw._start(self.metainterp_sd, None) + jitcode = cw.make_one_bytecode((graphs[0], None), False) + assert 'residual_call' not in jitcode._source + assert 'arraycopy' in jitcode._source class ImmutableFieldsTests: Modified: pypy/trunk/pypy/jit/metainterp/test/test_list.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_list.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_list.py Sun Mar 14 01:13:13 2010 @@ -118,6 +118,32 @@ assert res == f(10) py.test.skip("'[non-null] * n' gives a residual call so far") self.check_loops(setarrayitem_gc=0, getarrayitem_gc=0, call=0) + + def test_arraycopy_simpleoptimize(self): + def f(): + l = [1, 2, 3, 4] + l2 = l[:] + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.interp_operations(f, [], listops=True) + assert res == 10 + + def test_arraycopy_full(self): + jitdriver = JitDriver(greens = [], reds = ['n']) + def f(n): + l = [] + l2 = [] + while n > 0: + jitdriver.can_enter_jit(n=n) + jitdriver.jit_merge_point(n=n) + l = [1, 2, 3, n] + l2 = l[:] + n -= 1 + return l2[0] + l2[1] + l2[2] + l2[3] + + res = self.meta_interp(f, [5], listops=True) + assert res == 7 + self.check_loops(call=0) class TestOOtype(ListTests, OOJitMixin): pass Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 01:13:13 2010 @@ -2723,6 +2723,8 @@ """ self.optimize_loop(ops, 'Not, Not', expected) + def test_arraycopy_1(self): + pass class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): Modified: pypy/trunk/pypy/rlib/rgc.py ============================================================================== --- pypy/trunk/pypy/rlib/rgc.py (original) +++ pypy/trunk/pypy/rlib/rgc.py Sun Mar 14 01:13:13 2010 @@ -276,7 +276,7 @@ keepalive_until_here(dest) ll_arraycopy._annenforceargs_ = [None, None, int, int, int] ll_arraycopy._annspecialcase_ = 'specialize:ll' -ll_arraycopy._jit_look_inside_ = False +ll_arraycopy.oopspec = 'list.ll_arraycopy(source, dest, source_start, dest_start, length)' def ll_shrink_array(p, smallerlength): from pypy.rpython.lltypesystem.lloperation import llop @@ -310,7 +310,6 @@ ll_shrink_array._annspecialcase_ = 'specialize:ll' ll_shrink_array._jit_look_inside_ = False - def no_collect(func): func._dont_inline_ = True func._gc_no_collect_ = True From fijal at codespeak.net Sun Mar 14 03:11:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 03:11:14 +0100 (CET) Subject: [pypy-svn] r72214 - pypy/branch/arraycopy/pypy/jit/metainterp/test Message-ID: <20100314021114.DB6B9282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 03:11:12 2010 New Revision: 72214 Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Log: Write down a test for optimizeopt Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 03:11:12 2010 @@ -2724,7 +2724,20 @@ self.optimize_loop(ops, 'Not, Not', expected) def test_arraycopy_1(self): - pass + ops = ''' + [i0] + p1 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 1, 1, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + arraycopy(ConstPtr(myptr), ConstPtr(myptr), p1, p2, 1, 1, 2, descr=arraydescr) + i2 = getarrayitem_gc(p2, 1, descr=arraydescr) + jump(i2) + ''' + expected = ''' + [i0] + jump(1) + ''' + self.optimize_loop(ops, 'Not', expected) class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): From fijal at codespeak.net Sun Mar 14 03:16:54 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 03:16:54 +0100 (CET) Subject: [pypy-svn] r72215 - pypy/branch/arraycopy/pypy/jit/metainterp/test Message-ID: <20100314021654.2C278282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 03:16:52 2010 New Revision: 72215 Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Log: Write more tests, about indexes Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 03:16:52 2010 @@ -2729,7 +2729,8 @@ p1 = new_array(3, descr=arraydescr) setarrayitem_gc(p1, 1, 1, descr=arraydescr) p2 = new_array(3, descr=arraydescr) - arraycopy(ConstPtr(myptr), ConstPtr(myptr), p1, p2, 1, 1, 2, descr=arraydescr) + setarrayitem_gc(p2, 1, 3, descr=arraydescr) + arraycopy(0, 0, p1, p2, 1, 1, 2, descr=arraydescr) i2 = getarrayitem_gc(p2, 1, descr=arraydescr) jump(i2) ''' @@ -2739,6 +2740,23 @@ ''' self.optimize_loop(ops, 'Not', expected) + def test_arraycopy_2(self): + ops = ''' + [i0] + p1 = new_array(3, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p2, 0, 3, descr=arraydescr) + arraycopy(0, 0, p1, p2, 1, 1, 2, descr=arraydescr) + i2 = getarrayitem_gc(p2, 0, descr=arraydescr) + jump(i2) + ''' + expected = ''' + [i0] + jump(3) + ''' + self.optimize_loop(ops, 'Not', expected) + class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): def test_instanceof(self): From fijal at codespeak.net Sun Mar 14 04:16:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 04:16:34 +0100 (CET) Subject: [pypy-svn] r72216 - pypy/branch/arraycopy/pypy/jit/metainterp/test Message-ID: <20100314031634.3B577282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 04:16:32 2010 New Revision: 72216 Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Log: Write another test, which surprisingly passes. I think I'm good with the situation as it is now and will not try to improve it even further Modified: pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/branch/arraycopy/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 04:16:32 2010 @@ -2755,7 +2755,25 @@ [i0] jump(3) ''' - self.optimize_loop(ops, 'Not', expected) + self.optimize_loop(ops, 'Not', expected) + + def test_arraycopy_not_virtual(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 2, 10, descr=arraydescr) + setarrayitem_gc(p2, 2, 13, descr=arraydescr) + arraycopy(0, 0, p1, p2, 0, 0, 3, descr=arraydescr) + jump(p2) + ''' + expected = ''' + [p0] + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p2, 2, 10, descr=arraydescr) + jump(p2) + ''' + self.optimize_loop(ops, 'Not', expected) class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): From fijal at codespeak.net Sun Mar 14 04:17:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 04:17:18 +0100 (CET) Subject: [pypy-svn] r72217 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100314031718.13D34282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 04:17:16 2010 New Revision: 72217 Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: Finish merging the arraycopy branch - tests Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 04:17:16 2010 @@ -2724,7 +2724,56 @@ self.optimize_loop(ops, 'Not, Not', expected) def test_arraycopy_1(self): - pass + ops = ''' + [i0] + p1 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 1, 1, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p2, 1, 3, descr=arraydescr) + arraycopy(0, 0, p1, p2, 1, 1, 2, descr=arraydescr) + i2 = getarrayitem_gc(p2, 1, descr=arraydescr) + jump(i2) + ''' + expected = ''' + [i0] + jump(1) + ''' + self.optimize_loop(ops, 'Not', expected) + + def test_arraycopy_2(self): + ops = ''' + [i0] + p1 = new_array(3, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 0, i0, descr=arraydescr) + setarrayitem_gc(p2, 0, 3, descr=arraydescr) + arraycopy(0, 0, p1, p2, 1, 1, 2, descr=arraydescr) + i2 = getarrayitem_gc(p2, 0, descr=arraydescr) + jump(i2) + ''' + expected = ''' + [i0] + jump(3) + ''' + self.optimize_loop(ops, 'Not', expected) + + def test_arraycopy_not_virtual(self): + ops = ''' + [p0] + p1 = new_array(3, descr=arraydescr) + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p1, 2, 10, descr=arraydescr) + setarrayitem_gc(p2, 2, 13, descr=arraydescr) + arraycopy(0, 0, p1, p2, 0, 0, 3, descr=arraydescr) + jump(p2) + ''' + expected = ''' + [p0] + p2 = new_array(3, descr=arraydescr) + setarrayitem_gc(p2, 2, 10, descr=arraydescr) + jump(p2) + ''' + self.optimize_loop(ops, 'Not', expected) class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): From fijal at codespeak.net Sun Mar 14 04:17:38 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 04:17:38 +0100 (CET) Subject: [pypy-svn] r72218 - pypy/branch/arraycopy Message-ID: <20100314031738.EBA33282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 04:17:37 2010 New Revision: 72218 Removed: pypy/branch/arraycopy/ Log: remove merged branch From fijal at codespeak.net Sun Mar 14 04:35:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 04:35:55 +0100 (CET) Subject: [pypy-svn] r72219 - pypy/trunk/pypy/module/pypyjit/test Message-ID: <20100314033555.1618C282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 04:35:53 2010 New Revision: 72219 Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Log: A test for arraycopy branch merge Modified: pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py (original) +++ pypy/trunk/pypy/module/pypyjit/test/test_pypy_c.py Sun Mar 14 04:35:53 2010 @@ -586,6 +586,23 @@ assert len(bytecode.get_opnames('call')) == 2 # split_chr and list_pop assert len(bytecode2.get_opnames('call')) == 0 + def test_arraycopy_disappears(self): + self.run_source(''' + def main(): + i = 0 + while i < 100: + t = (1, 2, 3, i + 1) + t2 = t[:] + del t + i = t2[3] + del t2 + return i + ''', 100, ([], 100)) + bytecode, = self.get_by_bytecode('BINARY_SUBSCR') + assert len(bytecode.get_opnames('new_array')) == 1 + # XXX I would like here to say that it's 0, but unfortunately + # call that can raise is not exchanged into getarrayitem_gc + class AppTestJIT(PyPyCJITTests): def setup_class(cls): if not option.runappdirect: From fijal at codespeak.net Sun Mar 14 05:01:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 05:01:18 +0100 (CET) Subject: [pypy-svn] r72220 - pypy/extradoc/planning Message-ID: <20100314040118.1230E282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 05:01:17 2010 New Revision: 72220 Modified: pypy/extradoc/planning/jit.txt Log: done Modified: pypy/extradoc/planning/jit.txt ============================================================================== --- pypy/extradoc/planning/jit.txt (original) +++ pypy/extradoc/planning/jit.txt Sun Mar 14 05:01:17 2010 @@ -38,15 +38,6 @@ This is treated as a megamorphic call (promotion of w_self in typeobject.py) while in fact it is not. -- a recurring theme: we allocate an array, fill it with items, allocate new - array, copy_items, forget about first one. Would be cool to know that for - this case and some other cases, the static refcount can only be 1, so we - can optimize away the copy. - - I think enough would be to make jit aware of ll_arraycopy, so it knows - a copy of a virtual array yields another virtual array and will optimize - everything away on it's own. - - a suggestion - if we call some code via call_assembler that raises an exception, in theory we could do something smarter in case our frames don't escape and call simplified version that does not allocate all From fijal at codespeak.net Sun Mar 14 05:20:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 05:20:59 +0100 (CET) Subject: [pypy-svn] r72221 - in pypy/trunk/pypy/jit/metainterp: . test Message-ID: <20100314042059.0D53F282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 05:20:58 2010 New Revision: 72221 Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: A test and a trivial optimization Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Sun Mar 14 05:20:58 2010 @@ -927,6 +927,8 @@ val = source_value.getitem(index + source_start) dest_value.setitem(index + dest_start, val) return + if length and length.getint() == 0: + return # 0-length arraycopy descr = op.args[0] assert isinstance(descr, AbstractDescr) self.emit_operation(ResOperation(rop.CALL, op.args[1:], op.result, Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Sun Mar 14 05:20:58 2010 @@ -2775,6 +2775,21 @@ ''' self.optimize_loop(ops, 'Not', expected) + def test_arraycopy_no_elem(self): + """ this was actually observed in the wild + """ + ops = ''' + [p1] + p0 = new_array(0, descr=arraydescr) + arraycopy(0, 0, p0, p1, 0, 0, 0, descr=arraydescr) + jump(p1) + ''' + expected = ''' + [p1] + jump(p1) + ''' + self.optimize_loop(ops, 'Not', expected) + class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin): def test_instanceof(self): From magcius at codespeak.net Sun Mar 14 09:34:14 2010 From: magcius at codespeak.net (magcius at codespeak.net) Date: Sun, 14 Mar 2010 09:34:14 +0100 (CET) Subject: [pypy-svn] r72222 - in pypy/branch/avm/pypy/translator/avm2: . intrinsic test Message-ID: <20100314083414.37371282BF2@codespeak.net> Author: magcius Date: Sun Mar 14 09:34:11 2010 New Revision: 72222 Added: pypy/branch/avm/pypy/translator/avm2/conftest.py (contents, props changed) pypy/branch/avm/pypy/translator/avm2/sudanpython.py (contents, props changed) pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py (contents, props changed) Removed: pypy/branch/avm/pypy/translator/avm2/_intrinsic.py pypy/branch/avm/pypy/translator/avm2/abc_.py pypy/branch/avm/pypy/translator/avm2/assembler.py pypy/branch/avm/pypy/translator/avm2/constants.py pypy/branch/avm/pypy/translator/avm2/delegate.py pypy/branch/avm/pypy/translator/avm2/instructions.py pypy/branch/avm/pypy/translator/avm2/test/harness.py pypy/branch/avm/pypy/translator/avm2/test/runtest2.py pypy/branch/avm/pypy/translator/avm2/test/test.abc pypy/branch/avm/pypy/translator/avm2/test/test.swf pypy/branch/avm/pypy/translator/avm2/test/test_harness.py pypy/branch/avm/pypy/translator/avm2/traits.py pypy/branch/avm/pypy/translator/avm2/util.py Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py pypy/branch/avm/pypy/translator/avm2/class_.py pypy/branch/avm/pypy/translator/avm2/constant.py pypy/branch/avm/pypy/translator/avm2/function.py pypy/branch/avm/pypy/translator/avm2/genavm.py pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py pypy/branch/avm/pypy/translator/avm2/metavm.py pypy/branch/avm/pypy/translator/avm2/opcodes.py pypy/branch/avm/pypy/translator/avm2/query.py pypy/branch/avm/pypy/translator/avm2/test/ (props changed) pypy/branch/avm/pypy/translator/avm2/test/browsertest.py pypy/branch/avm/pypy/translator/avm2/test/runtest.py pypy/branch/avm/pypy/translator/avm2/test/test_string.py pypy/branch/avm/pypy/translator/avm2/types_.py Log: All tests in test_runtest.py pass Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/avm2gen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/avm2gen.py Sun Mar 14 09:34:11 2010 @@ -26,7 +26,7 @@ return self.cts.lltype_to_cts(TYPE) def get_class_context(self, name, DICT): - class_desc = query.Types.get(name, None) + class_desc = query.get_class_desc(name) if class_desc: BaseType = class_desc.BaseType if '.' in BaseType: @@ -34,10 +34,11 @@ else: ns, name = '', BaseType class_desc.super_name = constants.packagedQName(ns, name) + class_desc.name = constants.packagedQName(class_desc.Package, class_desc.ShortName) return class_desc else: return super(PyPyAvm2ilasm, self).get_class_context(name, DICT) - + def load(self, v, *args): if isinstance(v, flowmodel.Variable): if v.concretetype is ootype.Void: @@ -51,7 +52,7 @@ for e in args: self.load(e) - + # def prepare_call_oostring(self, OOTYPE): # self.I(instructions.findpropstrict(types._str_qname)) @@ -86,17 +87,21 @@ self.emit('findpropstrict', t) self.emit('constructprop', t, 0) - def array_setitem(self, ARRAY=None): + def array_setitem(self): self.I(instructions.setproperty(constants.MultinameL( constants.PROP_NAMESPACE_SET))) - # Hack: oosend expects a value to send to StoreResult + # XXX: oosend expects a value to send to StoreResult # We don't generate one, push a null. self.push_null() - def array_getitem(self, ARRAY=None): + def array_getitem(self): self.I(instructions.getproperty(constants.MultinameL( constants.PROP_NAMESPACE_SET))) - def array_length(self, ARRAY=None): + def array_length(self): self.I(instructions.getproperty(constants.QName("length"))) + def call_graph(self, graph, func_name=None): + if func_name is None: + self.db.pending_function(graph) + Modified: pypy/branch/avm/pypy/translator/avm2/class_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/class_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/class_.py Sun Mar 14 09:34:11 2010 @@ -16,6 +16,7 @@ self.db = db self.cts = db.genoo.TypeSystem(db) self.INSTANCE = INSTANCE + self.exception = ootype.isSubclass(self.INSTANCE, self.db.genoo.EXCEPTION) self.namespace = namespace self.name = name @@ -44,6 +45,8 @@ def get_base_class(self): base_class = self.INSTANCE._superclass + if self.INSTANCE is self.db.genoo.EXCEPTION: + return c.QName("Error") if self.is_root(base_class): return c.QName("Object") else: @@ -151,9 +154,10 @@ override = False else: override = True - print "Overriding toString" + print self.exception + wrapper = "Exception" if self.exception else "Instance" self.ilasm.begin_method('toString', [], types.types.string, override=override) - self.ilasm.load("InstanceWrapper('%s')" % (self.name)) + self.ilasm.load("%sWrapper('%s')" % (wrapper, self.name)) self.ilasm.emit('returnvalue') self.ilasm.exit_context() Added: pypy/branch/avm/pypy/translator/avm2/conftest.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/conftest.py Sun Mar 14 09:34:11 2010 @@ -0,0 +1,6 @@ +def pytest_addoption(parser): + group = parser.getgroup("pypy-tamarin options") + group.addoption('--swf', action="store_const", const="swf", dest="tamtarget", default="swf", + help="generate a swf and abc and use a browsertest to run") + group.addoption('--tamarin', action="store_const", const="tamarin", dest="tamtarget", + help="generate an abc that uses tamarin") Modified: pypy/branch/avm/pypy/translator/avm2/constant.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/constant.py (original) +++ pypy/branch/avm/pypy/translator/avm2/constant.py Sun Mar 14 09:34:11 2010 @@ -117,7 +117,7 @@ # ______________________________________________________________________ # Mixins # -# Mixins are used to add a few CLI-specific methods to each constant +# Mixins are used to add a few Tamarin-specific methods to each constant # class. Basically, any time I wanted to extend a base class (such as # AbstractConst or DictConst), I created a mixin, and then mixed it in # to each sub-class of that base-class. Kind of awkward. @@ -172,19 +172,49 @@ # and exist to combine a mixin and the generic base class. For now, # though, they contain the create_pointer() and initialize_data() # routines. In order to get rid of them, we would need to implement -# the generator interface in the CLI. +# the generator interface in Tamarin. class Avm2RecordConst(Avm2BaseConstMixin, RecordConst): def create_pointer(self, gen): self.db.const_count.inc('Record') super(Avm2RecordConst, self).create_pointer(gen) + def initialize_data(self, constgen, gen): + assert not self.is_null() + SELFTYPE = self.value._TYPE + for f_name, (FIELD_TYPE, f_default) in self.value._TYPE._fields.iteritems(): + if FIELD_TYPE is not ootype.Void: + gen.dup(SELFTYPE) + value = self.value._items[f_name] + push_constant(self.db, FIELD_TYPE, value, gen) + gen.set_field(f_name) + class Avm2InstanceConst(Avm2BaseConstMixin, InstanceConst): def create_pointer(self, gen): self.db.const_count.inc('Instance') self.db.const_count.inc('Instance', self.OOTYPE()) super(Avm2InstanceConst, self).create_pointer(gen) + def initialize_data(self, constgen, gen): + assert not self.is_null() + + # Get a list of all the constants we'll need to initialize. + # I am not clear on why this needs to be sorted, actually, + # but we sort it. + const_list = self._sorted_const_list() + + # Push ourself on the stack, and cast to our actual type if it + # is not the same as our static type + SELFTYPE = self.value._TYPE + if SELFTYPE is not self.static_type: + gen.downcast(SELFTYPE) + + # Store each of our fields in the sorted order + for FIELD_TYPE, INSTANCE, name, value in const_list: + constgen._consider_split_current_function(gen) + gen.dup(SELFTYPE) + push_constant(self.db, FIELD_TYPE, value, gen) + gen.set_field(name) class Avm2ClassConst(Avm2BaseConstMixin, ClassConst): def is_inline(self): Modified: pypy/branch/avm/pypy/translator/avm2/function.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/function.py (original) +++ pypy/branch/avm/pypy/translator/avm2/function.py Sun Mar 14 09:34:11 2010 @@ -133,7 +133,6 @@ def render_raise_block(self, block): exc = block.inputargs[1] - print exc self.generator.load(exc) self.generator.emit('throw') @@ -148,9 +147,9 @@ if isinstance(link.last_exception, flowmodel.Variable): self.ilasm.opcode('dup') self.store(link.last_exc_value) - self.ilasm.call_method( - 'class [mscorlib]System.Type object::GetType()', - virtual=True) + self.ilasm.emit('convert_o') + self.ilasm.get_field('prototype') + self.ilasm.get_field('constructor') self.store(link.last_exception) else: self.store(link.last_exc_value) Modified: pypy/branch/avm/pypy/translator/avm2/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm2/genavm.py Sun Mar 14 09:34:11 2010 @@ -1,5 +1,7 @@ import py +from mech.fusion.avm2.abc_ import AbcFile + from pypy.translator.oosupport.genoo import GenOO from pypy.translator.avm2.avm2gen import PyPyAvm2ilasm from pypy.translator.avm2.constant import Avm2ConstGenerator, Avm2ClassConst, Avm2InstanceConst, Avm2RecordConst, Avm2ArrayListConst @@ -27,10 +29,17 @@ GenOO.__init__(self, tmpdir, translator, entrypoint, config, exctrans) self.const_stat = str(tmpdir.join('const_stat')) self.ilasm = None - - def create_assembler(self): - return PyPyAvm2ilasm(self) + self.abc = None + rtyper = translator.rtyper + bk = rtyper.annotator.bookkeeper + clsdef = bk.getuniqueclassdef(Exception) + ll_Exception = rtyper.exceptiondata.get_standard_ll_exc_instance(rtyper, clsdef) + self.EXCEPTION = ll_Exception._inst._TYPE + def create_assembler(self): + self.abc = AbcFile() + return PyPyAvm2ilasm(self, self.abc) + def generate_source(self): if self.ilasm is None: self.ilasm = self.create_assembler() @@ -39,6 +48,9 @@ self.gen_pendings() self.db.gen_constants(self.ilasm) + def serialize_abc(self): + return self.abc.serialize() + # Don't do treebuilding stuff def stack_optimization(self): pass Modified: pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/intrinsic/intrgen.py Sun Mar 14 09:34:11 2010 @@ -7,29 +7,29 @@ from pypy.translator.avm2.query import ClassDesc -def get_ootype(t, resolved={}): +def get_type(t, resolved={}): if "=" in t: - return get_ootype(t.split("=")[0].strip(), resolved) + return get_type(t.split("=")[0].strip(), resolved) if t == "*": return "" elif t == "void": - return "ootype.Void" + return "None" elif t == "int": - return "ootype.SignedLongLong" + return "int" elif t == "uint": - return "ootype.UnsignedLongLong" + return "uint" elif t == "Boolean": - return "ootype.Bool" + return "bool" elif t == "Number": - return "ootype.Float" + return "float" elif t == "String": - return "ootype.String" + return "unicode" elif t == "Array": - return "ootype.List" + return "list" elif t.startswith("Vector.<"): - return get_ootype(t[len("Vector.<"):-1]) + "[]" + return get_type(t[len("Vector.<"):-1]) + "[]" elif t in ("Object", "Dictionary"): - return "ootype.Dict" + return "dict" return resolved.get(t, t) def parse_file(file): @@ -64,7 +64,15 @@ FullName = ShortName if "extends" in line: - BaseType = line[2] + name = line[2] + if os.path.exists(os.path.join(os.path.dirname(file.name), name+'.as')): + BaseType = '%s.%s' % (Package, name) + elif os.path.exists(os.path.join(intrinsic_dir, name+'.as')): + BaseType = name + elif name in Resolved: + BaseType = Resolved[name] + else: + BaseType = name elif line.startswith(("public function ", "public static function ")): @@ -87,10 +95,10 @@ if name == "!CONSTRUCTOR!": rettype = None else: - rettype = get_ootype(arglist[arglist.rfind(":")+2:], Resolved) + rettype = get_type(arglist[arglist.rfind(":")+2:], Resolved) args = [arg for arg in arglist[:arglist.find(")")].split(",")] - args = [(get_ootype(arg.strip().split(":")[1], Resolved) if ":" in arg else ("*args" if "..." in arg else arg.strip())) for arg in args] + args = [(get_type(arg.strip().split(":")[1], Resolved) if ":" in arg else ("*args" if "..." in arg else arg.strip())) for arg in args] if name in ("get", "set"): @@ -118,12 +126,13 @@ StaticFields.append(tuple(line[3].split(":"))) desc = ClassDesc() - desc.FullName = FullName - desc.BaseType = BaseType - desc.Package = Package - desc.Resolved = Resolved - desc.Methods = Methods - desc.Fields = Fields + desc.FullName = FullName + desc.ShortName = ShortName + desc.BaseType = BaseType + desc.Package = Package + desc.Resolved = Resolved + desc.Methods = Methods + desc.Fields = Fields desc.StaticMethods = StaticMethods desc.StaticFields = StaticFields @@ -132,8 +141,10 @@ def print_desc(desc): print print "desc = ClassDesc()" - print "desc.FullName = %r" % desc.FullName - print "desc.BaseType = %r" % desc.BaseType + print "desc.FullName = %r" % desc.FullName + print "desc.ShortName = %r" % desc.ShortName + print "desc.Package = %r" % desc.Package + print "desc.BaseType = %r" % desc.BaseType print_tuples("Methods", desc.Methods) print_tuples("StaticMethods", desc.StaticMethods) print_tuples("Fields", desc.Fields) Modified: pypy/branch/avm/pypy/translator/avm2/metavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/metavm.py (original) +++ pypy/branch/avm/pypy/translator/avm2/metavm.py Sun Mar 14 09:34:11 2010 @@ -1,9 +1,7 @@ -from pypy.translator.cli import oopspec from pypy.rpython.ootypesystem import ootype from pypy.translator.oosupport.metavm import MicroInstruction, \ PushAllArgs, StoreResult, GetField, SetField, DownCast from pypy.translator.oosupport.metavm import _Call as _OOCall -# from pypy.translator.cli.comparer import EqualityComparer from pypy.translator.avm2.runtime import _static_meth, NativeInstance from pypy.translator.avm2 import types_ as types from mech.fusion.avm2 import constants @@ -33,14 +31,15 @@ cts = generator.cts generator.emit() - def _load_arg_or_null(self, generator, arg): - if arg.concretetype is ootype.Void: - if arg.value is None: - generator.ilasm.push_null() # special-case: use None as a null value + def _load_arg_or_null(self, generator, *args): + for arg in args: + if arg.concretetype is ootype.Void: + if arg.value is None: + generator.ilasm.push_null() # special-case: use None as a null value + else: + assert False, "Don't know how to load this arg" else: - assert False, "Don't know how to load this arg" - else: - generator.load(arg) + generator.load(arg) class _CallMethod(_Call): @@ -51,32 +50,52 @@ def _render_method(self, generator, method_name, args): this = args[0] native = isinstance(this.concretetype, NativeInstance) - for arg in args: # push parametes - if native: - self._load_arg_or_null(generator, arg) - else: - generator.load(arg) + if native: + self._load_arg_or_null(generator, *args) + else: + generator.load(*args) if isinstance(this.concretetype, ootype.Array) and this.concretetype.ITEM is not ootype.Void: - v_array = args[0] - ARRAY = v_array.concretetype - if method_name == 'll_setitem_fast': - generator.array_setitem(ARRAY) - elif method_name == 'll_getitem_fast': - generator.array_getitem(ARRAY) - elif method_name == 'll_length': - generator.array_length(ARRAY) + if method_name == "ll_setitem_fast": + generator.array_setitem() + elif method_name == "ll_getitem_fast": + generator.array_getitem() + elif method_name == "ll_length": + generator.array_length() else: assert False + elif isinstance(this.concretetype, ootype.AbstractString): + if method_name == "ll_append": + generator.emit('add') + elif method_name == "ll_stritem_nonneg": + generator.call_method("charAt", 1) + elif method_name == "ll_strlen": + generator.get_field("length") else: - generator.call_method(this.concretetype, method_name) - + generator.call_method(method_name, len(args)-1) class _IndirectCall(_CallMethod): def render(self, generator, op): # discard the last argument because it's used only for analysis self._render_method(generator, 'Invoke', op.args[:-1]) +class ConstCall(MicroInstruction): + def __init__(self, method, *args): + self.__method = method + self.__args = args + + def render(self, generator, op): + generator.load(*self.__args) + generator.call_method(self.__method, len(self.__args)) + +class ConstCallArgs(MicroInstruction): + def __init__(self, method, numargs): + self.__method = method + self.__nargs = numargs + + def render(self, generator, op): + generator.call_method(self.__method, self.__nargs) + class _RuntimeNew(MicroInstruction): def render(self, generator, op): generator.load(op.args[0]) @@ -88,12 +107,29 @@ if op.args[1] == -1: generator.emit('findpropstrict', types.str_qname) generator.load(op.args[0]) - generator.emit('callproperty', 1) + generator.emit('callproperty', types.str_qname, 1) else: - generator.emit('findpropstrict', constants.QName("parseInt")) - generator.load(op.args[0]) - generator.load(op.args[1]) - generator.emit('callproperty', 2) + generator.load(*op.args) + generator.emit('callproperty', constants.QName("toString"), 1) + +class _OOParseInt(MicroInstruction): + def render(self, generator, op): + generator.load(*op.args) + generator.emit('getglobalscope') + generator.emit('callproperty', constants.QName("parseInt"), 2) + +class _OOParseFloat(MicroInstruction): + def render(self, generator, op): + generator.load(*op.args) + generator.emit('getglobalscope') + generator.emit('callproperty', constants.QName("parseFloat"), 1) + +class PushClass(MicroInstruction): + def __init__(self, classname): + self.__class = constants.QName(classname) + + def render(self, generator, op): + generator.emit('getlex', constants.QName(self.__class)) # class _NewCustomDict(MicroInstruction): # def render(self, generator, op): @@ -165,28 +201,23 @@ v_type, v_length = op.args assert v_type.concretetype is ootype.Void TYPE = v_type.value._INSTANCE - typetok = generator.cts.lltype_to_cts(TYPE) - generator.load(v_length) - generator.ilasm.opcode('newarr', typetok) + generator.oonewarray(TYPE, v_length) class _GetArrayElem(MicroInstruction): def render(self, generator, op): - generator.load(op.args[0]) - generator.load(op.args[1]) - rettype = generator.cts.lltype_to_cts(op.result.concretetype) - generator.ilasm.opcode('getproperty', rettype) + v_array, v_index = op.args + generator.load(v_array) + generator.get_field(str(v_index)) class _SetArrayElem(MicroInstruction): def render(self, generator, op): v_array, v_index, v_elem = op.args generator.load(v_array) - generator.load(v_index) if v_elem.concretetype is ootype.Void and v_elem.value is None: - generator.ilasm.opcode('ldnull') + generator.push_null() else: generator.load(v_elem) - elemtype = generator.cts.lltype_to_cts(v_array.concretetype) - generator.ilasm.opcode('stelem', elemtype) + generator.set_field(str(v_index)) class _TypeOf(MicroInstruction): def render(self, generator, op): @@ -198,6 +229,7 @@ else: cliClass = c_type.value fullname = cliClass._INSTANCE._name + generator.gettype() class _EventHandler(MicroInstruction): def render(self, generator, op): @@ -218,22 +250,18 @@ class _GetStaticField(MicroInstruction): def render(self, generator, op): - cli_class = op.args[0].value + cts_class = op.args[0].value fldname = op.args[1].value - TYPE = op.result.concretetype - cts_type = generator.cts.lltype_to_cts(TYPE) - desc = '%s::%s' % (cli_class._name, fldname) - generator.ilasm.load_static_field(cts_type, desc) + generator.ilasm.load(cts_class) + generator.ilasm.get_field(fldname) class _SetStaticField(MicroInstruction): def render(self, generator, op): - cli_class = op.args[0].value + cts_class = op.args[0].value fldname = op.args[1].value - TYPE = op.result.concretetype - cts_type = generator.cts.lltype_to_cts(TYPE) - desc = '%s::%s' % (cli_class._name, fldname) - generator.load(op.args[2]) - generator.ilasm.store_static_field(cts_type, desc) + generator.ilasm.load(cts_class) + generator.ilasm.swap() + generator.ilasm.set_field(fldname) class _FieldInfoForConst(MicroInstruction): def render(self, generator, op): @@ -278,4 +306,6 @@ SetStaticField = _SetStaticField() FieldInfoForConst = _FieldInfoForConst() OOString = _OOString() +OOParseInt = _OOParseInt() +OOParseFloat = _OOParseFloat() # CastPrimitive = _CastPrimitive() Modified: pypy/branch/avm/pypy/translator/avm2/opcodes.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/opcodes.py (original) +++ pypy/branch/avm/pypy/translator/avm2/opcodes.py Sun Mar 14 09:34:11 2010 @@ -1,8 +1,8 @@ from pypy.translator.avm2.metavm import Call, CallMethod, \ IndirectCall, GetField, SetField, DownCast, \ - NewArray, GetArrayElem, SetArrayElem,\ - TypeOf, EventHandler, GetStaticField, SetStaticField,\ - FieldInfoForConst, OOString + NewArray, GetArrayElem, SetArrayElem, OOParseInt, OOParseFloat, \ + TypeOf, EventHandler, GetStaticField, SetStaticField, \ + FieldInfoForConst, OOString, ConstCall, ConstCallArgs, PushClass from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\ New, RuntimeNew, CastTo, PushPrimitive, OONewArray from pypy.translator.cli.cts import WEAKREF @@ -44,21 +44,21 @@ # 'cli_getstaticfield': [GetStaticField], # 'cli_setstaticfield': [SetStaticField], # 'cli_fieldinfo_for_const': [FieldInfoForConst], - 'oois': 'ceq', -# 'oononnull': [PushAllArgs, 'ldnull', 'ceq']+Not, + 'oois': 'strictequals', + 'oononnull': [PushAllArgs, 'pushnull', 'equals', 'not'], 'classof': [PushAllArgs, 'callvirt instance class [mscorlib]System.Type object::GetType()'], - 'instanceof': [CastTo, 'ldnull', 'cgt.un'], - 'subclassof': [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'], + 'instanceof': [CastTo], + 'subclassof': [CastTo], 'ooidentityhash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'], 'oohash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'], 'oostring': [OOString], 'oounicode': [OOString], - 'ooparse_int': [PushAllArgs, 'call int32 [pypylib]pypy.runtime.Utils::OOParseInt(string, int32)'], - 'ooparse_float': [PushAllArgs, 'call float64 [pypylib]pypy.runtime.Utils::OOParseFloat(string)'], + 'ooparse_int': [PushAllArgs, OOParseInt], + 'ooparse_float': [PushAllArgs, OOParseFloat], # 'oonewcustomdict': [NewCustomDict], - 'oonewarray': [OONewArray, StoreResult], + 'oonewarray': [OONewArray], - 'hint': [PushArg(0), StoreResult], + 'hint': [PushArg(0)], 'direct_call': [Call], 'indirect_call': [IndirectCall], @@ -78,171 +78,171 @@ 'bool_not': [PushAllArgs]+Not, - 'int_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'], - 'int_neg': 'neg', + 'int_is_true': [PushAllArgs, PushPrimitive(ootype.Signed, 0), 'equals', 'not'], + 'int_neg': 'negate_i', # 'int_neg_ovf': _check_ovf(['ldc.i4.0', PushAllArgs, 'sub.ovf', StoreResult]), # 'int_abs': _abs('int32'), # 'int_abs_ovf': _check_ovf(_abs('int32')), 'int_invert': 'not', - 'uint_is_true': [PushAllArgs, 'ldc.i4.0', 'cgt.un'], + 'uint_is_true': [PushAllArgs, PushPrimitive(ootype.Unsigned, 0), 'greaterthan'], 'uint_invert': 'not', - 'float_is_true': [PushAllArgs, 'ldc.r8 0', 'ceq']+Not, - 'float_neg': 'neg', + 'float_is_true': [PushAllArgs, PushPrimitive(ootype.Float, 0), 'equals', 'not'], + 'float_neg': 'negate', # 'float_abs': _abs('float64'), - 'llong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'], - 'llong_neg': 'neg', + 'llong_is_true': [PushAllArgs, PushPrimitive(ootype.Signed, 0), 'equals', 'not'], + 'llong_neg': 'negate_i', # 'llong_neg_ovf': _check_ovf(['ldc.i8 0', PushAllArgs, 'sub.ovf', StoreResult]), # 'llong_abs': _abs('int64'), # 'llong_abs_ovf': _check_ovf(_abs('int64')), 'llong_invert': 'not', - 'ullong_is_true': [PushAllArgs, 'ldc.i8 0', 'cgt.un'], + 'ullong_is_true': [PushAllArgs, PushPrimitive(ootype.Unsigned, 0), 'greaterthan'], 'ullong_invert': 'not', # when casting from bool we want that every truth value is casted # to 1: we can't simply DoNothing, because the CLI stack could # contains a truth value not equal to 1, so we should use the !=0 # trick. - 'cast_bool_to_int': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not, - 'cast_bool_to_uint': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not, - 'cast_bool_to_float': [PushAllArgs, 'ldc.i4.0', 'ceq']+Not+['conv.r8'], - 'cast_char_to_int': DoNothing, - 'cast_unichar_to_int': DoNothing, - 'cast_int_to_char': DoNothing, - 'cast_int_to_unichar': DoNothing, - 'cast_int_to_uint': DoNothing, - 'cast_int_to_float': 'conv.r8', - 'cast_int_to_longlong': 'conv.i8', + 'cast_bool_to_int': 'convert_i', + 'cast_bool_to_uint': 'convert_u', + 'cast_bool_to_float': 'convert_d', + 'cast_char_to_int': [PushAllArgs, ConstCall("charCodeAt", 0)], + 'cast_unichar_to_int': [PushAllArgs, ConstCall("charCodeAt", 0)], + 'cast_int_to_char': [PushAllArgs, PushClass("String"), ConstCallArgs("fromCharCode", 1)], + 'cast_int_to_unichar': [PushAllArgs, PushClass("String"), ConstCallArgs("fromCharCode", 1)], + 'cast_int_to_uint': 'convert_i', + 'cast_int_to_float': 'convert_d', + 'cast_int_to_longlong': DoNothing, 'cast_uint_to_int': DoNothing, - 'cast_uint_to_float': [PushAllArgs, 'conv.u8', 'conv.r8'], - 'cast_float_to_int': 'conv.i4', - 'cast_float_to_uint': 'conv.u4', - 'cast_longlong_to_float': 'conv.r8', - 'cast_float_to_longlong': 'conv.i8', + 'cast_uint_to_float': 'convert_d', + 'cast_float_to_int': 'convert_i', + 'cast_float_to_uint': 'convert_u', + 'cast_longlong_to_float': 'convert_d', + 'cast_float_to_longlong': 'convert_i', # 'cast_primitive': [PushAllArgs, CastPrimitive], - 'truncate_longlong_to_int': 'conv.i4', + 'truncate_longlong_to_int': 'convert_i', } binary_ops = { - 'char_lt': 'clt', - 'char_le': _not('cgt'), - 'char_eq': 'ceq', - 'char_ne': _not('ceq'), - 'char_gt': 'cgt', - 'char_ge': _not('clt'), + 'char_lt': 'lessthan', + 'char_le': 'lessequals', + 'char_eq': 'equals', + 'char_ne': _not('equals'), + 'char_gt': 'greaterthan', + 'char_ge': 'greaterequals', 'unichar_eq': 'ceq', 'unichar_ne': _not('ceq'), - 'int_add': 'add', - 'int_sub': 'sub', - 'int_mul': 'mul', - 'int_floordiv': 'div', + 'int_add': 'add_i', + 'int_sub': 'subtract_i', + 'int_mul': 'multiply_i', + 'int_floordiv': [PushAllArgs, 'divide', 'convert_i'], # 'int_floordiv_zer': _check_zer('div'), - 'int_mod': 'rem', - 'int_lt': 'clt', - 'int_le': _not('cgt'), - 'int_eq': 'ceq', - 'int_ne': _not('ceq'), - 'int_gt': 'cgt', - 'int_ge': _not('clt'), - 'int_and': 'and', - 'int_or': 'or', - 'int_lshift': 'shl', - 'int_rshift': 'shr', - 'int_xor': 'xor', + 'int_mod': 'modulo', + 'int_lt': 'lessthan', + 'int_le': 'lessequals', + 'int_eq': 'equals', + 'int_ne': _not('equals'), + 'int_gt': 'greaterthan', + 'int_ge': 'greaterequals', + 'int_and': 'bitand', + 'int_or': 'bitor', + 'int_lshift': 'lshift', + 'int_rshift': 'rshift', + 'int_xor': 'bitxor', # 'int_add_ovf': _check_ovf('add.ovf'), # 'int_add_nonneg_ovf': _check_ovf('add.ovf'), # 'int_sub_ovf': _check_ovf('sub.ovf'), # 'int_mul_ovf': _check_ovf('mul.ovf'), - 'int_floordiv_ovf': 'div', # these can't overflow! - 'int_mod_ovf': 'rem', - 'int_lt_ovf': 'clt', - 'int_le_ovf': _not('cgt'), - 'int_eq_ovf': 'ceq', - 'int_ne_ovf': _not('ceq'), - 'int_gt_ovf': 'cgt', - 'int_ge_ovf': _not('clt'), - 'int_and_ovf': 'and', - 'int_or_ovf': 'or', + 'int_floordiv_ovf': 'divide', # these can't overflow! + 'int_mod_ovf': 'modulo', + 'int_lt_ovf': 'lessthan', + 'int_le_ovf': 'lessequals', + 'int_eq_ovf': 'equals', + 'int_ne_ovf': _not('equals'), + 'int_gt_ovf': 'greaterthan', + 'int_ge_ovf': 'greaterequals', + 'int_and_ovf': 'bitand', + 'int_or_ovf': 'bitor', # 'int_lshift_ovf': _check_ovf([PushArg(0),'conv.i8',PushArg(1), 'shl', # 'conv.ovf.i4', StoreResult]), # 'int_lshift_ovf_val': _check_ovf([PushArg(0),'conv.i8',PushArg(1), 'shl', # 'conv.ovf.i4', StoreResult]), - 'int_rshift_ovf': 'shr', # these can't overflow! - 'int_xor_ovf': 'xor', + 'int_rshift_ovf': 'rshift', # these can't overflow! + 'int_xor_ovf': 'bitxor', # 'int_floordiv_ovf_zer': _check_zer('div'), # 'int_mod_ovf_zer': _check_zer('rem'), # 'int_mod_zer': _check_zer('rem'), - 'uint_add': 'add', - 'uint_sub': 'sub', - 'uint_mul': 'mul', - 'uint_div': 'div.un', - 'uint_floordiv': 'div.un', - 'uint_mod': 'rem.un', - 'uint_lt': 'clt.un', - 'uint_le': _not('cgt.un'), - 'uint_eq': 'ceq', - 'uint_ne': _not('ceq'), - 'uint_gt': 'cgt.un', - 'uint_ge': _not('clt.un'), - 'uint_and': 'and', - 'uint_or': 'or', - 'uint_lshift': 'shl', - 'uint_rshift': 'shr.un', - 'uint_xor': 'xor', + 'uint_add': 'add_i', + 'uint_sub': 'subtract_i', + 'uint_mul': 'multiply_i', + 'uint_div': 'divide', + 'uint_floordiv': [PushAllArgs, 'divide', 'convert_u'], + 'uint_mod': 'modulo', + 'uint_lt': 'lessthan', + 'uint_le': 'lessequals', + 'uint_eq': 'equals', + 'uint_ne': _not('equals'), + 'uint_gt': 'greaterthan', + 'uint_ge': 'greaterequals', + 'uint_and': 'bitand', + 'uint_or': 'bitor', + 'uint_lshift': 'lshift', + 'uint_rshift': 'urshift', + 'uint_xor': 'bitxor', 'float_add': 'add', - 'float_sub': 'sub', - 'float_mul': 'mul', - 'float_truediv': 'div', - 'float_lt': 'clt', - 'float_le': _not('cgt'), - 'float_eq': 'ceq', - 'float_ne': _not('ceq'), - 'float_gt': 'cgt', - 'float_ge': _not('clt'), - - 'llong_add': 'add', - 'llong_sub': 'sub', - 'llong_mul': 'mul', - 'llong_div': 'div', - 'llong_floordiv': 'div', + 'float_sub': 'subtract', + 'float_mul': 'multiply', + 'float_truediv': 'divide', + 'float_lt': 'lessthan', + 'float_le': 'lessequals', + 'float_eq': 'equals', + 'float_ne': _not('equals'), + 'float_gt': 'greaterthan', + 'float_ge': 'greaterequals', + + 'llong_add': 'add_i', + 'llong_sub': 'subtract_i', + 'llong_mul': 'multiply_i', + 'llong_div': 'divide', + 'llong_floordiv': [PushAllArgs, 'divide', 'convert_i'], # 'llong_floordiv_zer': _check_zer('div'), - 'llong_mod': 'rem', + 'llong_mod': 'modulo', # 'llong_mod_zer': _check_zer('rem'), - 'llong_lt': 'clt', - 'llong_le': _not('cgt'), - 'llong_eq': 'ceq', - 'llong_ne': _not('ceq'), - 'llong_gt': 'cgt', - 'llong_ge': _not('clt'), - 'llong_and': 'and', - 'llong_or': 'or', - 'llong_lshift': 'shl', - 'llong_rshift': [PushAllArgs, 'conv.i4', 'shr'], - 'llong_xor': 'xor', - - 'ullong_add': 'add', - 'ullong_sub': 'sub', - 'ullong_mul': 'mul', - 'ullong_div': 'div.un', - 'ullong_floordiv': 'div.un', - 'ullong_mod': 'rem.un', - 'ullong_lt': 'clt.un', - 'ullong_le': _not('cgt.un'), - 'ullong_eq': 'ceq', - 'ullong_ne': _not('ceq'), - 'ullong_gt': 'cgt.un', - 'ullong_ge': _not('clt.un'), - 'ullong_lshift': [PushAllArgs, 'conv.u4', 'shl'], - 'ullong_rshift': [PushAllArgs, 'conv.i4', 'shr'], + 'llong_lt': 'lessthan', + 'llong_le': 'lessequals', + 'llong_eq': 'equals', + 'llong_ne': _not('equals'), + 'llong_gt': 'greaterthan', + 'llong_ge': 'lessthan', + 'llong_and': 'bitand', + 'llong_or': 'bitor', + 'llong_lshift': 'lshift', + 'llong_rshift': 'rshift', + 'llong_xor': 'bitxor', + + 'ullong_add': 'add_i', + 'ullong_sub': 'subtract_i', + 'ullong_mul': 'multiply_i', + 'ullong_div': 'divide', + 'ullong_floordiv': [PushAllArgs, 'divide', 'convert_u'], + 'ullong_mod': 'modulo', + 'ullong_lt': 'lessthan', + 'ullong_le': 'lessequals', + 'ullong_eq': 'equals', + 'ullong_ne': _not('equals'), + 'ullong_gt': 'greaterthan', + 'ullong_ge': 'greaterequals', + 'ullong_lshift': 'lshift', + 'ullong_rshift': 'urshift', } opcodes = misc_ops.copy() Modified: pypy/branch/avm/pypy/translator/avm2/query.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/query.py (original) +++ pypy/branch/avm/pypy/translator/avm2/query.py Sun Mar 14 09:34:11 2010 @@ -7,6 +7,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator import avm2 from pypy.translator.cli.support import log +from mech.fusion.avm2.constants import QName Types = {} # TypeName -> ClassDesc Namespaces = set() @@ -37,13 +38,12 @@ def load_playerglobal(): _cache = get_cachedir() outfile = _cache.join('avm2_playerglobal.pickle') - if outfile.check(): - f = outfile.open('rb') - types = pickle.load(f) - f.close() - else: - types = load_and_cache_playerglobal(outfile) - + ## if outfile.check(): + ## f = outfile.open('rb') + ## types = pickle.load(f) + ## f.close() + ## else: + types = load_and_cache_playerglobal(outfile) for ttype in types: parts = ttype.split('.') ns = parts[0] @@ -53,7 +53,6 @@ Namespaces.add(ns) Types.update(types) - def get_cachedir(): import pypy _cache = py.path.local(pypy.__file__).new(basename='_cache').ensure(dir=1) @@ -79,6 +78,13 @@ return avm2class._INSTANCE def get_class_desc(name): + + if isinstance(name, QName): + if name.ns.name: + name = '%s.%s' % (name.ns.name, name.name) + else: + name = name.name + if name in Types: return Types[name] @@ -95,11 +101,11 @@ ('get', ['ootype.Signed', ], itemdesc.FullName), ('set', ['ootype.Signed', itemdesc.FullName], 'ootype.Void') ] - else: - assert False, 'Unknown desc' + + Types[name] = desc + return desc - Types[name] = desc - return desc + return None class ClassDesc(object): @@ -180,6 +186,9 @@ RESULT = get_ootype(result) return Meth(ARGS, RESULT) + def __repr__(self): + return '' % (self.name,) + placeholder = object() class NativeNamespace(object): def __init__(self, name): @@ -203,7 +212,7 @@ setattr(parent, name, NativeNamespace(fullname)) else: setattr(self, fullname, NativeNamespace(fullname)) - + for fullname in Types.iterkeys(): if '.' in fullname: parent, name = fullname.rsplit('.', 1) Added: pypy/branch/avm/pypy/translator/avm2/sudanpython.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/sudanpython.py Sun Mar 14 09:34:11 2010 @@ -0,0 +1,160 @@ +#! /usr/bin/env python +""" +Usage: sudanpython.py [dll-name] + +Compiles an RPython module into a .abc file. +""" + +import sys +import new +import types +import os.path +import inspect + +from pypy.translator.driver import TranslationDriver +from pypy.translator.avm2.entrypoint import LibraryEntryPoint + +class AbcDef: + def __init__(self, name, namespace, functions=[], dontmangle=True, isnetmodule=False): + self.name = name + self.namespace = namespace + self.functions = functions # [(function, annotation), ...] + self.isnetmodule = isnetmodule + self.driver = TranslationDriver() + if dontmangle: + self.driver.config.translation.ootype.mangle = False + self.driver.setup_library(self) + + def add_function(self, func, inputtypes): + self.functions.append((func, inputtypes)) + + def get_entrypoint(self, bk): + graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions] + return LibraryEntryPoint(self.name, graphs, self.isnetmodule) + + def compile(self): + # add all functions to the appropriate namespace + if self.namespace: + for func, _ in self.functions: + if not hasattr(func, '_namespace_'): + func._namespace_ = self.namespace + self.driver.proceed(['compile_cli']) + +class export(object): + def __new__(self, *args, **kwds): + if len(args) == 1 and isinstance(args[0], types.FunctionType): + func = args[0] + func._inputtypes_ = () + return func + return object.__new__(self, *args, **kwds) + + def __init__(self, *args, **kwds): + self.inputtypes = args + self.namespace = kwds.pop('namespace', None) + if len(kwds) > 0: + raise TypeError, "unexpected keyword argument: '%s'" % kwds.keys()[0] + + def __call__(self, func): + func._inputtypes_ = self.inputtypes + if self.namespace is not None: + func._namespace_ = self.namespace + return func + +def is_exported(obj): + return isinstance(obj, (types.FunctionType, types.UnboundMethodType)) \ + and hasattr(obj, '_inputtypes_') + +def collect_entrypoints(dic): + entrypoints = [] + for item in dic.itervalues(): + if is_exported(item): + entrypoints.append((item, item._inputtypes_)) + elif isinstance(item, types.ClassType) or isinstance(item, type): + entrypoints += collect_class_entrypoints(item) + return entrypoints + +def collect_class_entrypoints(cls): + try: + __init__ = cls.__init__ + if not is_exported(__init__): + return [] + except AttributeError: + return [] + + entrypoints = [(wrap_init(cls, __init__), __init__._inputtypes_)] + for item in cls.__dict__.itervalues(): + if item is not __init__.im_func and is_exported(item): + inputtypes = (cls,) + item._inputtypes_ + entrypoints.append((wrap_method(item), inputtypes)) + return entrypoints + +def getarglist(meth): + arglist, starargs, kwargs, defaults = inspect.getargspec(meth) + assert starargs is None, '*args not supported yet' + assert kwargs is None, '**kwds not supported yet' + assert defaults is None, 'default values not supported yet' + return arglist + +def wrap_init(cls, meth): + arglist = getarglist(meth)[1:] # discard self + args = ', '.join(arglist) + source = 'def __internal__ctor(%s): return %s(%s)' % ( + args, cls.__name__, args) + mydict = {cls.__name__: cls} + print source + exec source in mydict + return mydict['__internal__ctor'] + +def wrap_method(meth, is_init=False): + arglist = getarglist(meth) + name = '__internal__%s' % meth.func_name + selfvar = arglist[0] + args = ', '.join(arglist) + params = ', '.join(arglist[1:]) + source = 'def %s(%s): return %s.%s(%s)' % ( + name, args, selfvar, meth.func_name, params) + mydict = {} + print source + exec source in mydict + return mydict[name] + + +def compile_abc(filename, abcname=None, copy_dll=True): + dirname, name = os.path.split(filename) + if abcname is None: + abcname, _ = os.path.splitext(name) + elif abcname.endswith('.abc'): + abcname, _ = os.path.splitext(abcname) + module = new.module(abcname) + namespace = module.__dict__.get('_namespace_', abcname) + sys.path.insert(0, dirname) + execfile(filename, module.__dict__) + sys.path.pop(0) + + dll = AbcDef(dllname, namespace) + dll.functions = collect_entrypoints(module.__dict__) + dll.compile() + if copy_dll: + dll.driver.copy_cli_dll() + +def main(argv): + if len(argv) == 2: + filename = argv[1] + dllname = None + elif len(argv) == 3: + filename = argv[1] + dllname = argv[2] + else: + print >> sys.stderr, __doc__ + sys.exit(2) + + if not filename.endswith('.py'): + filename += '.py' + if not os.path.exists(filename): + print >> sys.stderr, "Cannot find file %s" % filename + sys.exit(1) + compile_dll(filename, dllname) + +if __name__ == '__main__': + main(sys.argv) + Modified: pypy/branch/avm/pypy/translator/avm2/test/browsertest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/browsertest.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/browsertest.py Sun Mar 14 09:34:11 2010 @@ -1,18 +1,15 @@ -from BaseHTTPServer import HTTPServer as BaseHTTPServer, BaseHTTPRequestHandler +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from cgi import parse_qs import time import webbrowser -class HTTPServer(BaseHTTPServer): - allow_reuse_address = True - class config(object): http_port = 10001 html_page = """ -PyPy AVM Backend Test Case: %s +PyPy AVM2 Backend Test Case: %s @@ -26,27 +23,16 @@ """ -def parse_result(string): - if string.strip() == "": - return None - if string == "true": - return True - elif string == "false": - return False - elif string == "undefined" or string == "null": - return None - elif all(c in "123456789-" for c in string): - return int(string) - elif "," in string: - if string.startswith("(") and string.endswith(")"): - return tuple(parse_result(s) for s in string[1:-1].split(",") if parse_result(s) is not None) - return [parse_result(s) for s in string.split(",")] - else: - try: - return float(string) - except ValueError: - pass - return string +class InstanceWrapper: + def __init__(self, class_name): + self.class_name = class_name + +class ExceptionWrapper: + def __init__(self, class_name): + self.class_name = class_name + + def __repr__(self): + return 'ExceptionWrapper(%r)' % (self.class_name,) class TestCase(object): def __init__(self, name, swfdata): @@ -69,7 +55,7 @@ data = config.crossdomain_xml mime = 'text/xml' self.serve_data(mime, data) - + def do_POST(self): if self.path == "/test.result": form = parse_qs(self.rfile.read(int(self.headers['content-length']))) @@ -92,10 +78,7 @@ def get_result(self): testcase = self.httpd.testcase - start_time = time.time() while testcase.result is None: - if time.time() - start_time > 10: - assert False self.httpd.handle_request() return testcase.result @@ -105,4 +88,4 @@ driver.start_server(config.http_port, testcase) webbrowser.open('http://localhost:%d/test.html' % config.http_port) - return parse_result(driver.get_result()) + return driver.get_result() Added: pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py Sun Mar 14 09:34:11 2010 @@ -0,0 +1,161 @@ + +import py +from pypy.translator.avm2.test.browsertest import browsertest +from pypy.translator.avm2.avm2gen import PyPyAvm2ilasm + +from mech.fusion.swf.swfdata import SwfData +from mech.fusion.swf.tags import FileAttributes, SetBackgroundColor, \ + DefineEditText, SymbolClass, PlaceObject2, DoABC, ShowFrame, End +from mech.fusion.swf.records import Rect, RGBA + +from mech.fusion.avm2.constants import QName, packagedQName +from mech.fusion.avm2.traits import AbcSlotTrait + +class BaseTestEntryPoint(object): + def __init__(self, name, gen, wrap_exceptions): + self.excwrap = wrap_exceptions + self.name = name + self.swf = SwfData() + self.swf.add_tag(FileAttributes()) + self.swf.add_tag(SetBackgroundColor(0x333333)) + self.swf.add_tag(DefineEditText(Rect(0, 0, 600, 400), "", (''' +Running test %s. +If no text saying "Go:" appears below, the test probably had an error. +====================================================================== +'''.strip() % (name,)), color=RGBA(0xFFFFFF))) + self.swf.add_tag(PlaceObject2(1, 2, name="edittext")) + self.abc = DoABC("PyPy Main") + self.actions = PyPyAvm2ilasm(gen.db, self.abc) + + self.swf.add_tag(self.abc) + self.swf.add_tag(SymbolClass({0:"PyPyTest_EntryPoint"})) + self.swf.add_tag(ShowFrame()) + self.swf.add_tag(End()) + + def update_text(self): + pass + + def print_text(self, text): + self.actions.push_const(text) + self.actions.store_var('text') + self.update_text() + + def serialize_swf(self): + return self.swf.serialize() + + def print_var(self, prefix, varname): + self.actions.push_const(prefix) + self.actions.push_var(varname) + self.actions.emit('add') + self.actions.store_var('text') + self.update_text() + + def print_stack(self, prefix, dup=False): + if dup: + self.actions.dup() + self.actions.store_var('text') + self.update_text() + + def start_test_maincls(self): + pass + + def start_test(self): + self.start_test_maincls() + if self.excwrap: + self.actions.begin_try() + + def finish_test(self): + # WHHEEEEEEE! + if self.excwrap: + self.actions.end_try() + self.actions.emit('convert_s') + self.actions.branch_unconditionally("PyPy::ExceptionWrapLabel") + self.actions.begin_catch(QName("Error")) + self.actions.push_exception() + self.actions.emit('convert_s') + self.actions.end_catch() + self.actions.set_label("PyPy::ExceptionWrapLabel") + self.actions.store_var('result') + self.print_var("Got: ", 'result') + self.publish_test() + self.epilogue() + self.actions.finish() + + def do_test(self): + self.finish_test() + f = open("%s.swf" % (self.name,), "wb") + f.write(self.swf.serialize()) + f.close() + f = open("%s.abc" % (self.name,), "wb") + f.write(self.abc.serialize()) + f.close() + return browsertest(self.name, self.swf) + + def epilogue(self): + pass + + def publish_test(self): + pass + +class SWFTestEntryPoint(BaseTestEntryPoint): + def get_edittext(self): + if not self.actions.HL('edittext'): + self.actions.push_this() + self.actions.get_field('edittext') + self.actions.store_var('edittext') + self.actions.push_var('edittext') + + def update_text(self): + self.get_edittext() + self.actions.push_const("\n") + self.actions.push_var('text') + self.actions.emit('add') + self.actions.emit('callpropvoid', QName("appendText"), 1) + + def start_test_maincls(self): + self.maincls = self.actions.begin_class(QName("PyPyTest_EntryPoint"), packagedQName("flash.display", "Sprite")) + self.maincls.make_iinit() + self.maincls.add_instance_trait(AbcSlotTrait(QName("edittext"), packagedQName("flash.text", "TextField"))) + + def publish_test(self): + self.actions.emit('findpropstrict', packagedQName("flash.net", "URLRequest")) + self.actions.push_const('./test.result') + self.actions.emit('constructprop', packagedQName("flash.net", "URLRequest"), 1) + self.actions.store_var('request') + self.actions.push_var('request') + self.actions.push_const('POST') + self.actions.set_field('method') + self.actions.push_var('request') + self.actions.emit('findpropstrict', packagedQName("flash.net", "URLVariables")) + self.actions.emit('constructprop', packagedQName("flash.net", "URLVariables"), 0) + self.actions.set_field('data') + self.actions.push_var('request') + self.actions.get_field('data') + self.actions.push_var('result') + self.actions.set_field('result') + self.actions.emit('findpropstrict', packagedQName("flash.net", "sendToURL")) + self.actions.push_var('request') + self.actions.emit('callpropvoid', packagedQName("flash.net", "sendToURL"), 1) + self.actions.emit('findpropstrict', packagedQName("flash.net", "navigateToURL")) + self.actions.emit('findpropstrict', packagedQName("flash.net", "URLRequest")) + self.actions.push_const('javascript: self.close()') + self.actions.emit('constructprop', packagedQName("flash.net", "URLRequest"), 1) + self.actions.push_const('_self') + self.actions.emit('callpropvoid', packagedQName("flash.net", "navigateToURL"), 2) + +class TamarinTestEntryPoint(BaseTestEntryPoint): + def update_text(self): + self.actions.push_const("\n") + self.actions.get_field('text') + self.actions.emit('add') + self.actions.emit('findpropstrict', QName("print")) + self.actions.emit('callpropvoid', QName("print"), 1) + + def epilogue(self): + self.actions.exit_until_type("script") + self.actions.push_var('this') + self.actions.emit('constructprop', QName("PyPyTest_EntryPoint"), 0) + + def start_test_maincls(self): + self.maincls = self.actions.begin_class(QName("PyPyTest_EntryPoint")) + self.maincls.make_iinit() Modified: pypy/branch/avm/pypy/translator/avm2/test/runtest.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/runtest.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/runtest.py Sun Mar 14 09:34:11 2010 @@ -1,6 +1,8 @@ import platform +import sys import py +from pypy.conftest import option from pypy.translator.translator import TranslationContext from pypy.rpython.test.tool import BaseRtypingTest, OORtypeMixin from pypy.rpython.lltypesystem.lltype import typeOf @@ -9,26 +11,45 @@ from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.backendopt.checkvirtual import check_virtual_methods from pypy.translator.oosupport.support import patch_os, unpatch_os -from pypy.translator.avm2.test.harness import TestHarness +from pypy.translator.avm2.test.entrypoint import SWFTestEntryPoint, TamarinTestEntryPoint +from pypy.translator.avm2.test.browsertest import ExceptionWrapper, InstanceWrapper from pypy.translator.avm2.genavm import GenAVM2 -# def translate_space_op(gen, op): -# if op.opname == "cast_int_to_char": -# gen.push_arg(op.args[0]) -# gen.push_const(1) -# gen.push_var("String") -# gen.call_method("fromCharCode") +ENTRY_POINTS = dict(swf=SWFTestEntryPoint, tamarin=TamarinTestEntryPoint) + +def parse_result(string): + string = string.strip() + if string == "true": + return True + elif string == "false": + return False + elif string == "undefined" or string == "null": + return None + elif all(c in "123456789-" for c in string): + return int(string) + elif "," in string: + if string.startswith("(") and string.endswith(")"): + return tuple(parse_result(s) for s in string[1:-1].split(",")) + return [parse_result(s) for s in string.split(",")] + elif string.startswith("ExceptionWrapper"): + return eval(string) + else: + try: + return float(string) + except ValueError: + pass + return string def compile_function(func, name, annotation=[], graph=None, backendopt=True, - exctrans=False, annotatorpolicy=None): + exctrans=False, annotatorpolicy=None, wrapexc=False): olddefs = patch_os() - gen = _build_gen(func, annotation,graph, backendopt, + gen = _build_gen(func, annotation, graph, backendopt, exctrans, annotatorpolicy) - harness = TestHarness(name, gen) - gen.ilasm = harness.actions + entry_point = ENTRY_POINTS[option.tamtarget](name, gen, wrapexc) + gen.ilasm = entry_point.actions gen.generate_source() unpatch_os(olddefs) # restore original values - return gen, harness + return entry_point def _build_gen(func, annotation, graph=None, backendopt=True, exctrans=False, annotatorpolicy=None): @@ -51,10 +72,10 @@ if backendopt: check_virtual_methods(ootype.ROOT) backend_optimizations(t) - - if func.func_name in ("fn_view", "ident_view"): + + if option.view: t.view() - + main_graph = t.graphs[0] tmpdir = py.path.local('.') @@ -64,20 +85,27 @@ def __init__(self): self._func = None self._ann = None - self._genoo = None self._harness = None - def _compile(self, fn, args, ann=None, backendopt=True, exctrans=False): + def _compile(self, fn, args, ann=None, backendopt=True, exctrans=False, wrapexc=False): + + frame = sys._getframe() + while frame: + name = frame.f_code.co_name + if name.startswith("test_"): + break + frame = frame.f_back + else: + name = "test_unknown" + if ann is None: ann = [lltype_to_annotation(typeOf(x)) for x in args] - self._genoo, self._harness = compile_function(fn, - "%s.%s" % (self.__class__.__name__, fn.func_name), - ann, - backendopt=backendopt, - exctrans=exctrans) + + self._entry_point = compile_function(fn, "%s.%s" % (type(self).__name__, name), + ann, backendopt=backendopt, exctrans=exctrans, wrapexc=wrapexc) self._func = fn self._ann = ann - return self._harness + return self._entry_point def _skip_win(self, reason): if platform.system() == 'Windows': @@ -89,25 +117,29 @@ def _skip_llinterpreter(self, reason, skipLL=True, skipOO=True): pass - + def _get_backendopt(self, backendopt): if backendopt is None: backendopt = getattr(self, 'backendopt', True) # enable it by default return backendopt - def interpret(self, fn, args, annotation=None, backendopt=None, exctrans=False): + def interpret(self, fn, args, annotation=None, backendopt=None, exctrans=False, wrapexc=False): backendopt = self._get_backendopt(backendopt) - harness = self._compile(fn, args, annotation, backendopt=backendopt, exctrans=exctrans) - harness.start_test() - harness.actions.call_function_constargs(fn.func_name, *args) - result = harness.do_test(True) + entry_point = self._compile(fn, args, annotation, backendopt=backendopt, + exctrans=exctrans, wrapexc=wrapexc) + print entry_point + entry_point.start_test() + entry_point.actions.call_function_constargs(fn.func_name, *args) + result = parse_result(entry_point.do_test()) + if isinstance(result, ExceptionWrapper): + raise result return result def interpret_raises(self, exception, fn, args, backendopt=None, exctrans=False): import exceptions # needed by eval backendopt = self._get_backendopt(backendopt) try: - self.interpret(fn, args, backendopt=backendopt, exctrans=exctrans) + self.interpret(fn, args, backendopt=backendopt, exctrans=exctrans, wrapexc=True) except ExceptionWrapper, ex: assert issubclass(eval(ex.class_name), exception) else: @@ -138,14 +170,3 @@ def read_attr(self, obj, name): py.test.skip('read_attr not supported on gencli tests') - -class InstanceWrapper: - def __init__(self, class_name): - self.class_name = class_name - -class ExceptionWrapper: - def __init__(self, class_name): - self.class_name = class_name - - def __repr__(self): - return 'ExceptionWrapper(%s)' % repr(self.class_name) Modified: pypy/branch/avm/pypy/translator/avm2/test/test_string.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/test_string.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/test_string.py Sun Mar 14 09:34:11 2010 @@ -1,8 +1,8 @@ import py -from pypy.translator.cli.test.runtest import CliTest +from pypy.translator.avm2.test.runtest import AVM2Test import pypy.translator.oosupport.test_template.string as oostring -class TestCliString(CliTest, oostring.BaseTestString): +class TestAVM2String(AVM2Test, oostring.BaseTestString): EMPTY_STRING_HASH = 0 Modified: pypy/branch/avm/pypy/translator/avm2/types_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/types_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/types_.py Sun Mar 14 09:34:11 2010 @@ -98,8 +98,8 @@ ootype.Void: types.void, ootype.Signed: types.int, ootype.Unsigned: types.uint, - ootype.SignedLongLong: types.int, - ootype.UnsignedLongLong: types.uint, + ootype.SignedLongLong: types.float, + ootype.UnsignedLongLong: types.float, ootype.Bool: types.bool, ootype.Float: types.float, ootype.Char: types.string, From arigo at codespeak.net Sun Mar 14 17:58:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 14 Mar 2010 17:58:10 +0100 (CET) Subject: [pypy-svn] r72223 - in pypy/branch/jit-newx86/pypy/jit/backend/newx86: . test Message-ID: <20100314165810.DB9D1282BD4@codespeak.net> Author: arigo Date: Sun Mar 14 17:58:07 2010 New Revision: 72223 Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py (contents, props changed) pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py (contents, props changed) Log: Start the code buffer implementation. Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py ============================================================================== --- (empty file) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py Sun Mar 14 17:58:07 2010 @@ -0,0 +1,60 @@ +from pypy.rlib.objectmodel import we_are_translated +from pypy.rlib.rmmap import PTR, alloc, free +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.jit.backend.newx86.rx86 import X86_32_CodeBuilder, X86_64_CodeBuilder + + +class CodeBufAllocator(object): + def __init__(self, word): + self.all_data_parts = [] # only if we are not translated + self.alloc_count = 0 + self.cb_class = code_builder_cls[word] + + def __del__(self): + for data, size in self.all_data_parts: + free(data, size) + self.alloc_count -= 1 + + def new_code_buffer(self, map_size): + data = alloc(map_size) + if not we_are_translated(): + self.all_data_parts.append((data, map_size)) + return self.cb_class(data, map_size) + + +class CodeBufOverflow(Exception): + "Raised when a code buffer is full." + + +class CodeBuilder(object): + _mixin_ = True + raise_on_overflow = False + + def __init__(self, data, map_size): + self.data = data + self.write_ofs = map_size + + def writechar(self, char): + ofs = self.write_ofs - 1 + if ofs < 0: + self._overflow_detected() + self.data[ofs] = char + self.write_ofs = ofs + + def _overflow_detected(self): + assert self.raise_on_overflow + raise CodeBufOverflow + _overflow_detected._dont_inline_ = True + + def get_current_position(self): + return rffi.ptradd(self.data, self.write_ofs) + + +class CodeBuilder32(CodeBuilder, X86_32_CodeBuilder): + pass + +class CodeBuilder64(CodeBuilder, X86_64_CodeBuilder): + pass + +code_builder_cls = {4: CodeBuilder32, + 8: CodeBuilder64} Added: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py ============================================================================== --- (empty file) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Sun Mar 14 17:58:07 2010 @@ -0,0 +1,45 @@ +import py +import gc +from pypy.jit.backend.newx86.codebuf import CodeBufOverflow +from pypy.jit.backend.newx86.codebuf import CodeBufAllocator +from pypy.jit.backend.newx86.rx86 import R + + +class TestCodeBuilder: + WORD = 4 + + def setup_method(self, meth): + self.cballoc = CodeBufAllocator(self.WORD) + + def teardown_method(self, meth): + for i in range(5): + if self.cballoc.alloc_count == 0: + break + gc.collect() + else: + raise AssertionError("alloc_count == %d" % ( + self.cballoc.alloc_count,)) + + def test_alloc_free(self): + c1 = self.cballoc.new_code_buffer(4096) + c2 = self.cballoc.new_code_buffer(8192) + + def test_writing_from_end(self): + c = self.cballoc.new_code_buffer(4096) + c.RET() + c.NOP() + p1 = c.get_current_position() + assert p1[0] == chr(0x90) # NOP + assert p1[1] == chr(0xC3) # RET + c.PUSH_r(R.ecx) + p2 = c.get_current_position() + assert p2[0] == chr(0x51) # PUSH ecx + assert p2[1] == chr(0x90) # NOP + assert p2[2] == chr(0xC3) # RET + + def test_overflowing(self): + c = self.cballoc.new_code_buffer(4096) + c.raise_on_overflow = True + for i in range(4096): + c.NOP() + py.test.raises(CodeBufOverflow, c.NOP) From arigo at codespeak.net Sun Mar 14 18:11:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 14 Mar 2010 18:11:10 +0100 (CET) Subject: [pypy-svn] r72224 - in pypy/branch/jit-newx86/pypy/jit/backend/newx86: . test Message-ID: <20100314171110.70340282BD4@codespeak.net> Author: arigo Date: Sun Mar 14 18:11:08 2010 New Revision: 72224 Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Log: Subbuffers, to use for writing guard failure code and data. Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py Sun Mar 14 18:11:08 2010 @@ -1,6 +1,6 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.rmmap import PTR, alloc, free -from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.lltypesystem import rffi from pypy.jit.backend.newx86.rx86 import X86_32_CodeBuilder, X86_64_CodeBuilder @@ -49,6 +49,17 @@ def get_current_position(self): return rffi.ptradd(self.data, self.write_ofs) + def extract_subbuffer(self, subsize): + subbuf = self.data + if self.write_ofs < subsize: + self._overflow_detected() + self.write_ofs -= subsize + self.data = rffi.ptradd(self.data, subsize) + return self.__class__(subbuf, subsize) + + def is_full(self): + return self.write_ofs == 0 + class CodeBuilder32(CodeBuilder, X86_32_CodeBuilder): pass Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Sun Mar 14 18:11:08 2010 @@ -1,5 +1,6 @@ import py import gc +from pypy.rpython.lltypesystem import rffi from pypy.jit.backend.newx86.codebuf import CodeBufOverflow from pypy.jit.backend.newx86.codebuf import CodeBufAllocator from pypy.jit.backend.newx86.rx86 import R @@ -43,3 +44,42 @@ for i in range(4096): c.NOP() py.test.raises(CodeBufOverflow, c.NOP) + + def test_extract_subbuffer(self): + c1 = self.cballoc.new_code_buffer(4096) + c1.NOP() + c2 = c1.extract_subbuffer(3) + p1 = c1.get_current_position() + assert p1[0] == chr(0x90) # NOP + p2 = c2.get_current_position() + assert p2[4092] == chr(0x90) # NOP + assert not c2.is_full() + c2.RET() + c2.RET() + c2.RET() + p2 = c2.get_current_position() + assert p2[0] == chr(0xC3) # RET + assert p2[1] == chr(0xC3) # RET + assert p2[2] == chr(0xC3) # RET + assert p2[4095] == chr(0x90) # NOP + assert c2.is_full() + + def test_extract_subbuffer_overflow(self): + c = self.cballoc.new_code_buffer(4096) + c.raise_on_overflow = True + for i in range(4092): + c.NOP() + c1 = c.extract_subbuffer(3) + c1.RET() + c1.RET() + c1.RET() + c2 = c.extract_subbuffer(1) + c2.PUSH_r(R.edx) + p1 = c1.get_current_position() + assert p1[0] == chr(0xC3) # RET + assert p1[1] == chr(0xC3) # RET + assert p1[2] == chr(0xC3) # RET + assert p1[3] == chr(0x52) # PUSH edx + assert p1[4] == chr(0x90) # NOP + assert p1[4095] == chr(0x90) # NOP + py.test.raises(CodeBufOverflow, c.extract_subbuffer, 1) From arigo at codespeak.net Sun Mar 14 18:18:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 14 Mar 2010 18:18:51 +0100 (CET) Subject: [pypy-svn] r72225 - in pypy/branch/jit-newx86/pypy/jit/backend/newx86: . test Message-ID: <20100314171851.DFBD4282BD4@codespeak.net> Author: arigo Date: Sun Mar 14 18:18:49 2010 New Revision: 72225 Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Log: Bah. Messed up the test checking that all allocated buffers are freed. Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py Sun Mar 14 18:18:49 2010 @@ -5,19 +5,22 @@ class CodeBufAllocator(object): + alloc_count = 0 + def __init__(self, word): self.all_data_parts = [] # only if we are not translated - self.alloc_count = 0 self.cb_class = code_builder_cls[word] def __del__(self): - for data, size in self.all_data_parts: - free(data, size) - self.alloc_count -= 1 + if not we_are_translated(): + for data, size in self.all_data_parts: + free(data, size) + CodeBufAllocator.alloc_count -= 1 def new_code_buffer(self, map_size): data = alloc(map_size) if not we_are_translated(): + CodeBufAllocator.alloc_count += 1 self.all_data_parts.append((data, map_size)) return self.cb_class(data, map_size) Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Sun Mar 14 18:18:49 2010 @@ -10,16 +10,18 @@ WORD = 4 def setup_method(self, meth): + CodeBufAllocator.alloc_count = 0 self.cballoc = CodeBufAllocator(self.WORD) def teardown_method(self, meth): + del self.cballoc for i in range(5): - if self.cballoc.alloc_count == 0: + if CodeBufAllocator.alloc_count == 0: break gc.collect() else: raise AssertionError("alloc_count == %d" % ( - self.cballoc.alloc_count,)) + CodeBufAllocator.alloc_count,)) def test_alloc_free(self): c1 = self.cballoc.new_code_buffer(4096) From arigo at codespeak.net Sun Mar 14 18:40:07 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 14 Mar 2010 18:40:07 +0100 (CET) Subject: [pypy-svn] r72226 - in pypy/branch/jit-newx86/pypy/jit/backend/newx86: . test Message-ID: <20100314174007.2CA5F282BD4@codespeak.net> Author: arigo Date: Sun Mar 14 18:40:05 2010 New Revision: 72226 Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Log: Slowly learning the proper way of unit tests: make codebuf independent of rx86, including tests. Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/codebuf.py Sun Mar 14 18:40:05 2010 @@ -1,15 +1,14 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.rmmap import PTR, alloc, free -from pypy.rpython.lltypesystem import rffi -from pypy.jit.backend.newx86.rx86 import X86_32_CodeBuilder, X86_64_CodeBuilder +from pypy.rpython.lltypesystem import lltype, rffi class CodeBufAllocator(object): alloc_count = 0 - def __init__(self, word): + def __init__(self, cb_class): self.all_data_parts = [] # only if we are not translated - self.cb_class = code_builder_cls[word] + self.cb_class = cb_class def __del__(self): if not we_are_translated(): @@ -22,22 +21,28 @@ if not we_are_translated(): CodeBufAllocator.alloc_count += 1 self.all_data_parts.append((data, map_size)) - return self.cb_class(data, map_size) + return self.cb_class(data, map_size, True) + + def empty_code_buffer(self): + return self.cb_class(lltype.nullptr(PTR.TO), 0, True) class CodeBufOverflow(Exception): "Raised when a code buffer is full." -class CodeBuilder(object): +class AbstractCodeBuilder(object): _mixin_ = True - raise_on_overflow = False - def __init__(self, data, map_size): + def __init__(self, data, map_size, raise_on_overflow): self.data = data self.write_ofs = map_size + self.raise_on_overflow = raise_on_overflow def writechar(self, char): + """Writes a character at the *end* of buffer, and decrement the + current position. + """ ofs = self.write_ofs - 1 if ofs < 0: self._overflow_detected() @@ -50,25 +55,16 @@ _overflow_detected._dont_inline_ = True def get_current_position(self): + """Return the current position. Note that this starts at the end.""" return rffi.ptradd(self.data, self.write_ofs) - def extract_subbuffer(self, subsize): + def extract_subbuffer(self, subsize, raise_on_overflow): subbuf = self.data if self.write_ofs < subsize: self._overflow_detected() self.write_ofs -= subsize self.data = rffi.ptradd(self.data, subsize) - return self.__class__(subbuf, subsize) + return self.__class__(subbuf, subsize, raise_on_overflow) def is_full(self): return self.write_ofs == 0 - - -class CodeBuilder32(CodeBuilder, X86_32_CodeBuilder): - pass - -class CodeBuilder64(CodeBuilder, X86_64_CodeBuilder): - pass - -code_builder_cls = {4: CodeBuilder32, - 8: CodeBuilder64} Modified: pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py ============================================================================== --- pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py (original) +++ pypy/branch/jit-newx86/pypy/jit/backend/newx86/test/test_codebuf.py Sun Mar 14 18:40:05 2010 @@ -3,7 +3,7 @@ from pypy.rpython.lltypesystem import rffi from pypy.jit.backend.newx86.codebuf import CodeBufOverflow from pypy.jit.backend.newx86.codebuf import CodeBufAllocator -from pypy.jit.backend.newx86.rx86 import R +from pypy.jit.backend.newx86.codebuf import AbstractCodeBuilder class TestCodeBuilder: @@ -11,7 +11,7 @@ def setup_method(self, meth): CodeBufAllocator.alloc_count = 0 - self.cballoc = CodeBufAllocator(self.WORD) + self.cballoc = CodeBufAllocator(AbstractCodeBuilder) def teardown_method(self, meth): del self.cballoc @@ -29,59 +29,61 @@ def test_writing_from_end(self): c = self.cballoc.new_code_buffer(4096) - c.RET() - c.NOP() + c.writechar('A') + c.writechar('B') p1 = c.get_current_position() - assert p1[0] == chr(0x90) # NOP - assert p1[1] == chr(0xC3) # RET - c.PUSH_r(R.ecx) + assert p1[0] == 'B' + assert p1[1] == 'A' + c.writechar('C') p2 = c.get_current_position() - assert p2[0] == chr(0x51) # PUSH ecx - assert p2[1] == chr(0x90) # NOP - assert p2[2] == chr(0xC3) # RET + assert p2[0] == 'C' + assert p2[1] == 'B' + assert p2[2] == 'A' def test_overflowing(self): c = self.cballoc.new_code_buffer(4096) - c.raise_on_overflow = True for i in range(4096): - c.NOP() - py.test.raises(CodeBufOverflow, c.NOP) + c.writechar('x') + py.test.raises(CodeBufOverflow, c.writechar, 'x') def test_extract_subbuffer(self): c1 = self.cballoc.new_code_buffer(4096) - c1.NOP() - c2 = c1.extract_subbuffer(3) + c1.writechar('x') + c2 = c1.extract_subbuffer(3, False) p1 = c1.get_current_position() - assert p1[0] == chr(0x90) # NOP + assert p1[0] == 'x' p2 = c2.get_current_position() - assert p2[4092] == chr(0x90) # NOP + assert p2[4092] == 'x' assert not c2.is_full() - c2.RET() - c2.RET() - c2.RET() + c2.writechar('1') + c2.writechar('2') + c2.writechar('3') p2 = c2.get_current_position() - assert p2[0] == chr(0xC3) # RET - assert p2[1] == chr(0xC3) # RET - assert p2[2] == chr(0xC3) # RET - assert p2[4095] == chr(0x90) # NOP + assert p2[0] == '3' + assert p2[1] == '2' + assert p2[2] == '1' + assert p2[4095] == 'x' assert c2.is_full() def test_extract_subbuffer_overflow(self): c = self.cballoc.new_code_buffer(4096) - c.raise_on_overflow = True for i in range(4092): - c.NOP() - c1 = c.extract_subbuffer(3) - c1.RET() - c1.RET() - c1.RET() - c2 = c.extract_subbuffer(1) - c2.PUSH_r(R.edx) + c.writechar('x') + c1 = c.extract_subbuffer(3, False) + c1.writechar('1') + c1.writechar('2') + c1.writechar('3') + c2 = c.extract_subbuffer(1, False) + c2.writechar('4') p1 = c1.get_current_position() - assert p1[0] == chr(0xC3) # RET - assert p1[1] == chr(0xC3) # RET - assert p1[2] == chr(0xC3) # RET - assert p1[3] == chr(0x52) # PUSH edx - assert p1[4] == chr(0x90) # NOP - assert p1[4095] == chr(0x90) # NOP - py.test.raises(CodeBufOverflow, c.extract_subbuffer, 1) + assert p1[0] == '3' + assert p1[1] == '2' + assert p1[2] == '1' + assert p1[3] == '4' + assert p1[4] == 'x' + assert p1[4095] == 'x' + py.test.raises(CodeBufOverflow, c.extract_subbuffer, 1, False) + + def test_empty_code_buffer(self): + c = self.cballoc.empty_code_buffer() + py.test.raises(CodeBufOverflow, c.writechar, 'x') From fijal at codespeak.net Sun Mar 14 21:24:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 21:24:49 +0100 (CET) Subject: [pypy-svn] r72227 - pypy/trunk/pypy/translator/goal Message-ID: <20100314202449.62E8F282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 21:24:46 2010 New Revision: 72227 Modified: pypy/trunk/pypy/translator/goal/ann_override.py Log: Try to be smart and have two different specializations for wrap__str and wrap__None_str Modified: pypy/trunk/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/trunk/pypy/translator/goal/ann_override.py (original) +++ pypy/trunk/pypy/translator/goal/ann_override.py Sun Mar 14 21:24:46 2010 @@ -68,6 +68,9 @@ builder = specialize.make_constgraphbuilder(2, factory=fold, srcmodule='') return funcdesc.cachedgraph((typ, x), builder=builder) + if typ is str: + if args_s[1].can_be_None: + typ = (None, str) return funcdesc.cachedgraph(typ) def _remember_immutable(pol, t, cached): From fijal at codespeak.net Sun Mar 14 21:33:05 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 14 Mar 2010 21:33:05 +0100 (CET) Subject: [pypy-svn] r72228 - pypy/build/bot2/pypybuildbot Message-ID: <20100314203305.D8FC3282BF2@codespeak.net> Author: fijal Date: Sun Mar 14 21:33:04 2010 New Revision: 72228 Modified: pypy/build/bot2/pypybuildbot/master.py Log: According to my calculations running benchmarks should not overlap with tests with these settings, but it's far more US-friendly Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Sun Mar 14 21:33:04 2010 @@ -125,7 +125,7 @@ MACOSX32], hour=4, minute=45), Nightly("nightly-benchmark", [JITBENCH], - hour=2, minute=25), + hour=6, minute=15), ], 'status': [status], From fijal at codespeak.net Mon Mar 15 00:40:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 15 Mar 2010 00:40:39 +0100 (CET) Subject: [pypy-svn] r72230 - pypy/trunk/pypy/interpreter Message-ID: <20100314234039.B8FEB282B9C@codespeak.net> Author: fijal Date: Mon Mar 15 00:40:38 2010 New Revision: 72230 Modified: pypy/trunk/pypy/interpreter/argument.py Log: combine wrapped is not needed if someone passes things like f(*args) when args is an empty object Modified: pypy/trunk/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/argument.py (original) +++ pypy/trunk/pypy/interpreter/argument.py Mon Mar 15 00:40:38 2010 @@ -99,7 +99,8 @@ make_sure_not_resized(self.keywords_w) make_sure_not_resized(self.arguments_w) - if w_stararg is not None or w_starstararg is not None: + if ((w_stararg is not None and w_stararg) or + (w_starstararg is not None and w_starstararg)): self._combine_wrapped(w_stararg, w_starstararg) # if we have a call where * or ** args are used at the callsite # we shouldn't let the JIT see the argument matching From fijal at codespeak.net Mon Mar 15 01:53:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 15 Mar 2010 01:53:00 +0100 (CET) Subject: [pypy-svn] r72231 - pypy/trunk/lib-python/modified-2.5.2 Message-ID: <20100315005300.14E53282B9C@codespeak.net> Author: fijal Date: Mon Mar 15 01:52:58 2010 New Revision: 72231 Modified: pypy/trunk/lib-python/modified-2.5.2/socket.py Log: Avoid creating *args calls all over the place. I'm honestly inclined to remove all exec there and simply write down methods (also docstrings don't have to be in _socket) Modified: pypy/trunk/lib-python/modified-2.5.2/socket.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/socket.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/socket.py Mon Mar 15 01:52:58 2010 @@ -123,8 +123,8 @@ _socketmethods = ( 'bind', 'connect', 'connect_ex', 'fileno', 'listen', - 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', - 'sendall', 'setblocking', + 'getpeername', 'getsockname', 'setsockopt', + 'setblocking', 'settimeout', 'gettimeout', 'shutdown') if sys.platform == "riscos": @@ -198,11 +198,34 @@ type = property(lambda self: self._sock.type, doc="the socket type") proto = property(lambda self: self._sock.proto, doc="the socket protocol") - _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" - "%s.__doc__ = _realsocket.%s.__doc__\n") + def sendall(self, data, flags=0): + """sendall(data[, flags]) + + Send a data string to the socket. For the optional flags + argument, see the Unix manual. This calls send() repeatedly + until all data is sent. If an error occurs, it's impossible + to tell how much data has been sent. + """ + self._sock.sendall(data, flags) + + def getsockopt(self, level, optname, buflen=None): + """getsockopt(level, option[, buffersize]) -> value + + Get a socket option. See the Unix manual for level and option. + If a nonzero buffersize argument is given, the return value is a + string of that length; otherwise it is an integer. + """ + if buflen is None: + return self._sock.getsockopt(level, optname) + return self._sock.getsockopt(level, optname, buflen) + + _s = ("def %(name)s(self, %(args)s): return self._sock.%(name)s(%(args)s)\n\n" + "%(name)s.__doc__ = _realsocket.%(name)s.__doc__\n") for _m in _socketmethods: - exec _s % (_m, _m, _m, _m) - del _m, _s + # yupi! we're on pypy, all code objects have this interface + argcount = getattr(_realsocket, _m).im_func.func_code.co_argcount - 1 + exec _s % {'name': _m, 'args': ', '.join(['arg%d' % i for i in range(argcount)])} + del _m, _s, i, argcount socket = SocketType = _socketobject From magcius at codespeak.net Mon Mar 15 02:01:02 2010 From: magcius at codespeak.net (magcius at codespeak.net) Date: Mon, 15 Mar 2010 02:01:02 +0100 (CET) Subject: [pypy-svn] r72232 - in pypy/branch/avm/pypy/translator/avm2: . test Message-ID: <20100315010102.7A0C4282B9C@codespeak.net> Author: magcius Date: Mon Mar 15 02:01:00 2010 New Revision: 72232 Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py pypy/branch/avm/pypy/translator/avm2/class_.py pypy/branch/avm/pypy/translator/avm2/constant.py pypy/branch/avm/pypy/translator/avm2/database.py pypy/branch/avm/pypy/translator/avm2/function.py pypy/branch/avm/pypy/translator/avm2/genavm.py pypy/branch/avm/pypy/translator/avm2/query.py pypy/branch/avm/pypy/translator/avm2/sudanpython.py pypy/branch/avm/pypy/translator/avm2/test/mylib.py pypy/branch/avm/pypy/translator/avm2/test/test_carbonpython.py pypy/branch/avm/pypy/translator/avm2/types_.py Log: More work on tests and sudanpython Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/avm2gen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/avm2gen.py Mon Mar 15 02:01:00 2010 @@ -12,6 +12,8 @@ from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.metavm import Generator from pypy.translator.oosupport.constant import push_constant +from pypy.translator.oosupport.function import render_sub_op + from itertools import chain @@ -19,7 +21,7 @@ def __init__(self, db, abc): super(PyPyAvm2ilasm, self).__init__(abc) - self.db = db + self.db = db self.cts = db.genoo.TypeSystem(db) def _get_type(self, TYPE): @@ -47,6 +49,8 @@ self.push_local(v) elif isinstance(v, flowmodel.Constant): push_constant(self.db, v.concretetype, v.value, self) + elif isinstance(v, SubOperation): + render_sub_op(v, self.db, self) else: super(PyPyAvm2ilasm, self).load(v) @@ -102,6 +106,36 @@ self.I(instructions.getproperty(constants.QName("length"))) def call_graph(self, graph, func_name=None): + """ + Call a graph. + """ if func_name is None: self.db.pending_function(graph) + func_name = func_name or graph.name + namespace = getattr(graph.func, '_namespace_', None) + if namespace: + qname = constants.packagedQName(namespace, func_name) + else: + qname = constants.QName(func_name) + self.emit('findpropstrict', qname) + self.emit('callproperty', qname) + + def store(self, v): + """ + Pop a value off the stack and store it in the variable. + """ + self.store_var(v.name) + + def push_local(self, v): + """ + Get the local occupied to "name" and push it to the stack. + """ + self.push_var(v.name) + + push_arg = push_local + def new(self, TYPE): + # XXX: assume no args for now + TYPE = self._get_type(TYPE) + self.emit('findpropstrict', TYPE) + self.emit('constructprop', TYPE, 0) Modified: pypy/branch/avm/pypy/translator/avm2/class_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/class_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/class_.py Mon Mar 15 02:01:00 2010 @@ -1,7 +1,6 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.cli.node import Node from pypy.translator.oosupport.constant import push_constant -from pypy.translator.cli.ilgenerator import CLIBaseGenerator from mech.fusion.avm2 import constants as c, traits from pypy.translator.avm2 import types_ as types Modified: pypy/branch/avm/pypy/translator/avm2/constant.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/constant.py (original) +++ pypy/branch/avm/pypy/translator/avm2/constant.py Mon Mar 15 02:01:00 2010 @@ -1,36 +1,9 @@ -""" -___________________________________________________________________________ -CLI Constants - -This module extends the oosupport/constant.py to be specific to the -CLI. Most of the code in this file is in the constant generators, which -determine how constants are stored and loaded (static fields, lazy -initialization, etc), but some constant classes have been overloaded or -extended to allow for special handling. - -The CLI implementation is broken into three sections: - -* Constant Generators: different generators implementing different - techniques for loading constants (Static fields, singleton fields, etc) - -* Mixins: mixins are used to add a few CLI-specific methods to each - constant class. Basically, any time I wanted to extend a base class - (such as AbstractConst or DictConst), I created a mixin, and then - mixed it in to each sub-class of that base-class. - -* Subclasses: here are the CLI specific classes. Eventually, these - probably wouldn't need to exist at all (the JVM doesn't have any, - for example), or could simply have empty bodies and exist to - combine a mixin and the generic base class. For now, though, they - contain the create_pointer() and initialize_data() routines. -""" from pypy.translator.oosupport.constant import \ push_constant, WeakRefConst, StaticMethodConst, CustomDictConst, \ ListConst, ClassConst, InstanceConst, RecordConst, DictConst, \ BaseConstantGenerator, AbstractConst, ArrayConst from pypy.rpython.ootypesystem import ootype -from pypy.translator.cli.comparer import EqualityComparer from pypy.translator.avm2 import types_ as types from pypy.rpython.lltypesystem import lltype @@ -38,10 +11,6 @@ CONST_CLASS = constants.packagedQName("pypy.runtime", "Constants") -DEBUG_CONST_INIT = False -DEBUG_CONST_INIT_VERBOSE = False -SERIALIZE = False - # ______________________________________________________________________ # Constant Generators # @@ -97,6 +66,15 @@ def _store_constant(self, gen, const): gen.emit('initproperty', constants.QName(const.name)) + def _initialize_data(self, gen, all_constants): + """ Iterates through each constant, initializing its data. """ + for const in all_constants: + self._consider_step(gen) + self._push_constant_during_init(gen, const) + self.current_const = const + if not const.initialize_data(self, gen): + gen.pop() + def _declare_step(self, gen, stepnum): pass @@ -184,7 +162,7 @@ SELFTYPE = self.value._TYPE for f_name, (FIELD_TYPE, f_default) in self.value._TYPE._fields.iteritems(): if FIELD_TYPE is not ootype.Void: - gen.dup(SELFTYPE) + gen.dup() value = self.value._items[f_name] push_constant(self.db, FIELD_TYPE, value, gen) gen.set_field(f_name) @@ -212,7 +190,7 @@ # Store each of our fields in the sorted order for FIELD_TYPE, INSTANCE, name, value in const_list: constgen._consider_split_current_function(gen) - gen.dup(SELFTYPE) + gen.dup() push_constant(self.db, FIELD_TYPE, value, gen) gen.set_field(name) @@ -251,15 +229,14 @@ self.db.const_count.inc('List', self.value._TYPE.ITEM) self.db.const_count.inc('List', llen) gen.oonewarray(self.value._TYPE, llen) - + def initialize_data(self, constgen, gen): assert not self.is_null() # check for special cases and avoid initialization if self._do_not_initialize(): return - - # set each item in the list using the OOTYPE methods + for idx, item in enumerate(self.value._array): gen.dup() gen.emit('setproperty', constants.Multiname( Modified: pypy/branch/avm/pypy/translator/avm2/database.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/database.py (original) +++ pypy/branch/avm/pypy/translator/avm2/database.py Mon Mar 15 02:01:00 2010 @@ -1,7 +1,6 @@ import string #from pypy.translator.avm.class_ import Class from pypy.rpython.ootypesystem import ootype -from pypy.translator.cli.support import Counter from pypy.translator.avm2 import runtime, types_ as types, class_ as c, record from pypy.translator.oosupport.database import Database as OODatabase @@ -10,6 +9,23 @@ except NameError: from sets import Set as set +class Counter(object): + def __init__(self): + self.counters = {} + + def inc(self, *label): + cur = self.counters.get(label, 0) + self.counters[label] = cur+1 + + def dump(self, filename): + f = file(filename, 'w') + keys = self.counters.keys() + keys.sort() + for key in keys: + label = ', '.join([str(item) for item in key]) + f.write('%s: %d\n' % (label, self.counters[key])) + f.close() + class LowLevelDatabase(OODatabase): def __init__(self, genoo): OODatabase.__init__(self, genoo) Modified: pypy/branch/avm/pypy/translator/avm2/function.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/function.py (original) +++ pypy/branch/avm/pypy/translator/avm2/function.py Mon Mar 15 02:01:00 2010 @@ -45,21 +45,24 @@ def begin_render(self): self._set_args() self._set_locals() - print self.args - print self.locals if not self.args: self.args = () + if self.is_method: + self.args = self.args[1:] + returntype, returnvar = self.cts.llvar_to_cts(self.graph.getreturnvar()) if self.classname: - self.generator.begin_method(self.name, self.args[1:], returntype, override=self.override) - else: - self.generator.begin_method(self.name, self.args, returntype, static=True, override=self.override) + self.generator.begin_class(constants.packagedQName(self.namespace, self.classname)) + + self.generator.begin_method(self.name, self.args, returntype, static=not self.is_method, override=self.override) def end_render(self): # if self.generator.scope.islabel: # self.generator.exit_scope() + if self.classname: + self.generator.exit_context() self.generator.exit_context() def render_return_block(self, block): Modified: pypy/branch/avm/pypy/translator/avm2/genavm.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/genavm.py (original) +++ pypy/branch/avm/pypy/translator/avm2/genavm.py Mon Mar 15 02:01:00 2010 @@ -38,7 +38,7 @@ def create_assembler(self): self.abc = AbcFile() - return PyPyAvm2ilasm(self, self.abc) + return PyPyAvm2ilasm(self.db, self.abc) def generate_source(self): if self.ilasm is None: @@ -52,5 +52,5 @@ return self.abc.serialize() # Don't do treebuilding stuff - def stack_optimization(self): - pass + # def stack_optimization(self): + # pass Modified: pypy/branch/avm/pypy/translator/avm2/query.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/query.py (original) +++ pypy/branch/avm/pypy/translator/avm2/query.py Mon Mar 15 02:01:00 2010 @@ -6,7 +6,6 @@ from pypy.tool.udir import udir from pypy.rpython.ootypesystem import ootype from pypy.translator import avm2 -from pypy.translator.cli.support import log from mech.fusion.avm2.constants import QName Types = {} # TypeName -> ClassDesc @@ -35,6 +34,12 @@ # clr.AddReference(pypylib) # load_assembly(pypylib) +def getattr_ex(target, attr): + parts = attr.split('.') + for part in parts: + target = getattr(target, part) + return target + def load_playerglobal(): _cache = get_cachedir() outfile = _cache.join('avm2_playerglobal.pickle') @@ -203,7 +208,6 @@ def _buildtree(self): assert self._name is None, '_buildtree can be called only on top-level Runtime, not on namespaces' - from pypy.translator.cli.support import getattr_ex load_playerglobal() for fullname in sorted(list(Namespaces)): if '.' in fullname: Modified: pypy/branch/avm/pypy/translator/avm2/sudanpython.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/sudanpython.py (original) +++ pypy/branch/avm/pypy/translator/avm2/sudanpython.py Mon Mar 15 02:01:00 2010 @@ -15,11 +15,10 @@ from pypy.translator.avm2.entrypoint import LibraryEntryPoint class AbcDef: - def __init__(self, name, namespace, functions=[], dontmangle=True, isnetmodule=False): + def __init__(self, name, namespace, functions=[], dontmangle=True): self.name = name self.namespace = namespace self.functions = functions # [(function, annotation), ...] - self.isnetmodule = isnetmodule self.driver = TranslationDriver() if dontmangle: self.driver.config.translation.ootype.mangle = False @@ -30,7 +29,7 @@ def get_entrypoint(self, bk): graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions] - return LibraryEntryPoint(self.name, graphs, self.isnetmodule) + return LibraryEntryPoint(self.name, graphs) def compile(self): # add all functions to the appropriate namespace @@ -38,7 +37,7 @@ for func, _ in self.functions: if not hasattr(func, '_namespace_'): func._namespace_ = self.namespace - self.driver.proceed(['compile_cli']) + self.driver.proceed(['compile_tamarin']) class export(object): def __new__(self, *args, **kwds): @@ -119,7 +118,7 @@ return mydict[name] -def compile_abc(filename, abcname=None, copy_dll=True): +def compile_abc(filename, abcname=None): dirname, name = os.path.split(filename) if abcname is None: abcname, _ = os.path.splitext(name) @@ -131,11 +130,9 @@ execfile(filename, module.__dict__) sys.path.pop(0) - dll = AbcDef(dllname, namespace) - dll.functions = collect_entrypoints(module.__dict__) - dll.compile() - if copy_dll: - dll.driver.copy_cli_dll() + abc = AbcDef(abcname, namespace) + abc.functions = collect_entrypoints(module.__dict__) + abc.compile() def main(argv): if len(argv) == 2: @@ -153,7 +150,7 @@ if not os.path.exists(filename): print >> sys.stderr, "Cannot find file %s" % filename sys.exit(1) - compile_dll(filename, dllname) + compile_abc(filename, dllname) if __name__ == '__main__': main(sys.argv) Modified: pypy/branch/avm/pypy/translator/avm2/test/mylib.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/mylib.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/mylib.py Mon Mar 15 02:01:00 2010 @@ -1,4 +1,4 @@ -from pypy.translator.cli.carbonpython import export +from pypy.translator.avm2.sudanpython import export @export(int, int) def sum(a, b): Modified: pypy/branch/avm/pypy/translator/avm2/test/test_carbonpython.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/test_carbonpython.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/test_carbonpython.py Mon Mar 15 02:01:00 2010 @@ -4,7 +4,7 @@ import os import os.path from pypy.tool import udir -from pypy.translator.cli.rte import Target +from pypy.translator.cli.1rte import Target from pypy.translator.cli.carbonpython import DllDef, export, collect_entrypoints,\ collect_class_entrypoints, compile_dll from pypy.translator.cli.test.runtest import CliFunctionWrapper, CliTest Modified: pypy/branch/avm/pypy/translator/avm2/types_.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/types_.py (original) +++ pypy/branch/avm/pypy/translator/avm2/types_.py Mon Mar 15 02:01:00 2010 @@ -88,10 +88,9 @@ # weakref = CliClassType('pypylib', 'pypy.runtime.WeakReference') type = T('Class') object = T('Object') - # list = N('List', 'pypy.lib') list = Avm2ArrayType - dict = N('Dict', 'pypy.lib') - sb = N('StringBuilder', 'pypy.lib') + dict = T('Object') +# sb = N('StringBuilder', 'pypy.lib') del T _lltype_to_cts = { @@ -105,10 +104,10 @@ ootype.Char: types.string, ootype.UniChar: types.string, ootype.Class: types.type, - ootype.String: types.string, - ootype.StringBuilder: types.sb, - ootype.Unicode: types.string, - ootype.UnicodeBuilder: types.sb, +# ootype.String: types.string, +# ootype.StringBuilder: types.sb, +# ootype.Unicode: types.string, +# ootype.UnicodeBuilder: types.sb, # maps generic types to their ordinal ootype.List.SELFTYPE_T: types.list, @@ -175,6 +174,14 @@ def escape_name(self, name): return name + + def graph_to_qname(self, graph): + func_name = self.graph.name + namespace = getattr(self.graph, '_namespace_', None) + if namespace: + return constants.packagedQName(namespace, func_name) + else: + return constants.QName(func_name) # def ctor_name(self, t): # return 'instance void %s::.ctor()' % self.lltype_to_cts(t) From fijal at codespeak.net Mon Mar 15 03:33:40 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 15 Mar 2010 03:33:40 +0100 (CET) Subject: [pypy-svn] r72234 - pypy/branch/blackhole-improvement Message-ID: <20100315023340.3B2D8282B9C@codespeak.net> Author: fijal Date: Mon Mar 15 03:33:38 2010 New Revision: 72234 Added: pypy/branch/blackhole-improvement/ - copied from r72233, pypy/trunk/ Log: Try again branching to speedup blackhole From arigo at codespeak.net Mon Mar 15 13:13:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 15 Mar 2010 13:13:44 +0100 (CET) Subject: [pypy-svn] r72237 - pypy/trunk/pypy/translator/platform Message-ID: <20100315121344.8DA6C282B9C@codespeak.net> Author: arigo Date: Mon Mar 15 13:13:43 2010 New Revision: 72237 Modified: pypy/trunk/pypy/translator/platform/posix.py pypy/trunk/pypy/translator/platform/windows.py Log: Tweak the Makefile to separate CFLAGS and CFLAGSEXTRA, so that the latter gives flags available even if we type for example 'make lldebug'. No test, sorry. Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Mon Mar 15 13:13:43 2010 @@ -87,8 +87,10 @@ ('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)), + ('CFLAGS', self.cflags), + ('CFLAGSEXTRA', list(eci.compile_extra)), + ('LDFLAGS', self.link_flags), + ('LDFLAGSEXTRA', list(eci.link_extra)), ('CC', self.cc), ('CC_LINK', eci.use_cpp_linker and 'g++' or '$(CC)'), ('LINKFILES', eci.link_files), @@ -98,8 +100,8 @@ rules = [ ('all', '$(DEFAULT_TARGET)', []), - ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) $(LINKFILES)'), - ('%.o', '%.c', '$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)'), + ('$(TARGET)', '$(OBJECTS)', '$(CC_LINK) $(LDFLAGS) $(LDFLAGSEXTRA) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) $(LINKFILES)'), + ('%.o', '%.c', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) -o $@ -c $< $(INCLUDEDIRS)'), ] for rule in rules: @@ -123,6 +125,7 @@ def write(self, f): def write_list(prefix, lst): + lst = lst or [''] for i, fn in enumerate(lst): fn = fn.replace('\\', '\\\\') print >> f, prefix, fn, @@ -136,9 +139,8 @@ f.write('%s = %s\n' % (name, value.replace('\\', '\\\\'))) else: write_list('%s =' % (name,), value) - if value: - f.write('\n') - + f.write('\n') + class Rule(object): def __init__(self, target, deps, body): self.target = target Modified: pypy/trunk/pypy/translator/platform/windows.py ============================================================================== --- pypy/trunk/pypy/translator/platform/windows.py (original) +++ pypy/trunk/pypy/translator/platform/windows.py Mon Mar 15 13:13:43 2010 @@ -236,8 +236,10 @@ ('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)), + ('CFLAGS', self.cflags), + ('CFLAGSEXTRA', list(eci.compile_extra)), + ('LDFLAGS', self.link_flags), + ('LDFLAGSEXTRA', list(eci.link_extra)), ('CC', self.cc), ('CC_LINK', self.link), ('MASM', self.masm), @@ -247,7 +249,7 @@ rules = [ ('all', '$(DEFAULT_TARGET)', []), - ('.c.obj', '', '$(CC) /nologo $(CFLAGS) /Fo$@ /c $< $(INCLUDEDIRS)'), + ('.c.obj', '', '$(CC) /nologo $(CFLAGS) $(CFLAGSEXTRA) /Fo$@ /c $< $(INCLUDEDIRS)'), ] for rule in rules: @@ -255,10 +257,10 @@ if self.version < 80: m.rule('$(TARGET)', '$(OBJECTS)', - '$(CC_LINK) /nologo $(LDFLAGS) $(OBJECTS) /out:$@ $(LIBDIRS) $(LIBS)') + '$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA) $(OBJECTS) /out:$@ $(LIBDIRS) $(LIBS)') else: m.rule('$(TARGET)', '$(OBJECTS)', - ['$(CC_LINK) /nologo $(LDFLAGS) $(OBJECTS) /out:$@ $(LIBDIRS) $(LIBS) /MANIFESTFILE:$*.manifest', + ['$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA) $(OBJECTS) /out:$@ $(LIBDIRS) $(LIBS) /MANIFESTFILE:$*.manifest', 'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1', ]) From afa at codespeak.net Mon Mar 15 13:18:29 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 15 Mar 2010 13:18:29 +0100 (CET) Subject: [pypy-svn] r72238 - pypy/trunk/pypy/module/_ssl Message-ID: <20100315121829.95CB5282B9C@codespeak.net> Author: afa Date: Mon Mar 15 13:18:28 2010 New Revision: 72238 Modified: pypy/trunk/pypy/module/_ssl/interp_ssl.py Log: Compilation fails sometimes on Windows when openssl/ssl.h is included before other libraries. This is Yet Another Winsock.h Mess, which separate compilation will probably solve. Modified: pypy/trunk/pypy/module/_ssl/interp_ssl.py ============================================================================== --- pypy/trunk/pypy/module/_ssl/interp_ssl.py (original) +++ pypy/trunk/pypy/module/_ssl/interp_ssl.py Mon Mar 15 13:18:28 2010 @@ -13,13 +13,19 @@ if sys.platform == 'win32' and platform.name != 'mingw32': libraries = ['libeay32', 'ssleay32', 'user32', 'advapi32', 'gdi32'] + includes = [ + # ssl.h includes winsock.h, which will conflict with our own + # need of winsock2. Remove this when separate compilation is + # available... + 'winsock2.h', + 'openssl/ssl.h'] else: libraries = ['ssl', 'crypto'] + includes = ['openssl/ssl.h'] eci = ExternalCompilationInfo( libraries = libraries, - includes = ['openssl/ssl.h', - ], + includes = includes, export_symbols = ['SSL_load_error_strings'], ) From afa at codespeak.net Mon Mar 15 13:21:48 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 15 Mar 2010 13:21:48 +0100 (CET) Subject: [pypy-svn] r72239 - pypy/trunk/pypy/tool Message-ID: <20100315122148.A9CBF282B9C@codespeak.net> Author: afa Date: Mon Mar 15 13:21:47 2010 New Revision: 72239 Modified: pypy/trunk/pypy/tool/win32-build.bat Log: Save the last version of the tool, the one used to build the official pypy-1.2-win32.zip Modified: pypy/trunk/pypy/tool/win32-build.bat ============================================================================== --- pypy/trunk/pypy/tool/win32-build.bat (original) +++ pypy/trunk/pypy/tool/win32-build.bat Mon Mar 15 13:21:47 2010 @@ -3,23 +3,36 @@ set ROOTDIR=%~dp0..\.. cd %ROOTDIR% +set ZIPEXE=zip set PYTHON=c:\python26\python.exe set TRANSLATE=pypy/translator/goal/translate.py set TRANSLATEOPTS=--batch set TARGET=pypy/translator/goal/targetpypystandalone set TARGETOPTS= -%PYTHON% %TRANSLATE% --output=pypy-c.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% -%PYTHON% %TRANSLATE% -Ojit --output=pypy-jit.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% -%PYTHON% %TRANSLATE% --stackless --output=pypy-stackless.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% -%PYTHON% %TRANSLATE% --sandbox --output=pypy-sandbox.exe %TRANSLATEOPTS% %TARGET% %TARGETOPTS% - -set ZIP=zip.exe -set ZIPFILE=pypy-1.2-win32.zip -copy ..\expat-2.0.1\win32\bin\release\libexpat.dll . +copy /y ..\expat-2.0.1\win32\bin\release\libexpat.dll . +call :make_pypy pypy-1.2-win32.zip pypy.exe -Ojit +call :make_pypy pypy-1.2-win32-nojit.zip pypy-nojit.exe +call :make_pypy pypy-1.2-win32-stackless.zip pypy-stackless.exe --stackless +REM call :make_pypy pypy-1.2-win32-sandbox.zip pypy-sandbox.exe --sandbox + +goto :EOF + +REM ========================================= +:make_pypy +REM make_pypy subroutine +REM %1 is the zip filename +REM %2 is pypy.exe filename +REM %3 and others are the translation options + +set ZIPFILE=%1 +set PYPYEXE=%2 +set EXTRAOPTS=%3 %4 %5 %6 %7 %8 %9 + +%PYTHON% %TRANSLATE% --output=%PYPYEXE% %TRANSLATEOPTS% %EXTRAOPTS% %TARGET% %TARGETOPTS% +del %ZIPFILE% del /s pypy\lib\*.pyc lib-python\*.pyc -del %ZIPFILE% -%ZIP% %ZIPFILE% *.exe *.dll -%ZIP% -r %ZIPFILE% pypy\lib lib-python -%ZIP% -d %ZIPFILE% lib-python\2.5.2\plat-* +%ZIPEXE% %ZIPFILE% %PYPYEXE% *.dll +%ZIPEXE% -r %ZIPFILE% pypy\lib lib-python +%ZIPEXE% -d %ZIPFILE% lib-python\2.5.2\plat-* From getxsick at codespeak.net Mon Mar 15 14:14:23 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 15 Mar 2010 14:14:23 +0100 (CET) Subject: [pypy-svn] r72241 - pypy/build/ubuntu/debian/source Message-ID: <20100315131423.513D3282B9C@codespeak.net> Author: getxsick Date: Mon Mar 15 14:14:21 2010 New Revision: 72241 Removed: pypy/build/ubuntu/debian/source/ Log: Backport to dpkg-source 1.0 format. Ubuntu doesn't support 3.0 format (it should be available in 10.4) From arigo at codespeak.net Mon Mar 15 14:37:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 15 Mar 2010 14:37:21 +0100 (CET) Subject: [pypy-svn] r72242 - pypy/trunk/pypy/translator/c/src Message-ID: <20100315133721.C0FD3282B9C@codespeak.net> Author: arigo Date: Mon Mar 15 14:37:20 2010 New Revision: 72242 Modified: pypy/trunk/pypy/translator/c/src/debug_print.h Log: Silence a warning on Windows. Modified: pypy/trunk/pypy/translator/c/src/debug_print.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/debug_print.h (original) +++ pypy/trunk/pypy/translator/c/src/debug_print.h Mon Mar 15 14:37:20 2010 @@ -116,7 +116,7 @@ * This is the default generic timestamp implementation. */ # ifdef _WIN32 -# define READ_TIMESTAMP(val) QueryPerformanceCounter(&(val)) +# define READ_TIMESTAMP(val) QueryPerformanceCounter((LARGE_INTEGER*)&(val)) # else # include # include From afa at codespeak.net Mon Mar 15 16:17:07 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 15 Mar 2010 16:17:07 +0100 (CET) Subject: [pypy-svn] r72248 - pypy/trunk/pypy/translator/c/gcc Message-ID: <20100315151707.8440E282B9C@codespeak.net> Author: afa Date: Mon Mar 15 16:16:53 2010 New Revision: 72248 Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Log: Add support in trackgcroot.py for the /arch:SS2 option on Windows. Don't enable it yet, since I reliably crash on the first gc collection. Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Mon Mar 15 16:16:53 2010 @@ -368,12 +368,12 @@ return [] IGNORE_OPS_WITH_PREFIXES = dict.fromkeys([ - 'cmp', 'test', 'set', 'sahf', 'cltd', 'cld', 'std', + 'cmp', 'test', 'set', 'sahf', 'lahf', 'cltd', 'cld', 'std', 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'prefetch', # floating-point operations cannot produce GC pointers 'f', - 'cvt', 'ucomi', 'subs', 'subp' , 'adds', 'addp', 'xorp', 'movap', - 'movd', 'movlp', 'sqrtsd', + 'cvt', 'ucomi', 'comi', 'subs', 'subp' , 'adds', 'addp', 'xorp', + 'movap', 'movd', 'movlp', 'sqrtsd', 'mins', 'minp', 'maxs', 'maxp', 'unpck', 'pxor', 'por', # sse2 # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', @@ -381,6 +381,8 @@ 'bswap', 'bt', 'rdtsc', # zero-extending moves should not produce GC pointers 'movz', + # quadword operations + 'movq', ]) visit_movb = visit_nop @@ -1176,11 +1178,18 @@ # with other modules. if line.startswith("PUBLIC\t__real@"): line = '; ' + line + if line.startswith("PUBLIC\t__mask@@"): + line = '; ' + line elif line.startswith("PUBLIC\t??_C@"): line = '; ' + line elif line == "PUBLIC\t__$ArrayPad$\n": line = '; ' + line + # The msvc compiler writes "fucomip ST(1)" when the correct + # syntax is "fucomip ST, ST(1)" + if line == "\tfucomip\tST(1)\n": + line = "\tfucomip\tST, ST(1)\n" + # Because we insert labels in the code, some "SHORT" jumps # are now longer than 127 bytes. We turn them all into # "NEAR" jumps. Note that the assembler allocates space From fijal at codespeak.net Mon Mar 15 17:49:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 15 Mar 2010 17:49:17 +0100 (CET) Subject: [pypy-svn] r72250 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100315164917.0C03A282B9C@codespeak.net> Author: fijal Date: Mon Mar 15 17:49:16 2010 New Revision: 72250 Added: pypy/extradoc/talk/oopsla2010/ Log: create an empty dir From arigo at codespeak.net Mon Mar 15 17:56:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 15 Mar 2010 17:56:46 +0100 (CET) Subject: [pypy-svn] r72251 - pypy/trunk/pypy/translator/c Message-ID: <20100315165646.C640C282BE2@codespeak.net> Author: arigo Date: Mon Mar 15 17:56:44 2010 New Revision: 72251 Modified: pypy/trunk/pypy/translator/c/genc.py Log: Bah. Forgot this with r72237. Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Mon Mar 15 17:56:44 2010 @@ -524,7 +524,7 @@ mk.definition('OBJECTS', 'gcmaptable.obj $(ASMLBLOBJFILES)') # /Oi (enable intrinsics) and /Ob1 (some inlining) are mandatory # even in debug builds - mk.definition('ASM_CFLAGS', '$(CFLAGS) /Oi /Ob1') + mk.definition('ASM_CFLAGS', '$(CFLAGS) $(CFLAGSEXTRA) /Oi /Ob1') mk.rule('.SUFFIXES', '.s', []) mk.rule('.s.obj', '', 'cmd /c $(MASM) /nologo /Cx /Cp /Zm /coff /Fo$@ /c $< $(INCLUDEDIRS)') @@ -537,7 +537,7 @@ else: mk.definition('OBJECTS', '$(ASMLBLFILES) gcmaptable.s') - mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') + mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) $(CFLAGSEXTRA) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)') mk.rule('%.lbl.s %.gcmap', '%.s', python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $*.gcmap') mk.rule('gcmaptable.s', '$(GCMAPFILES)', From fijal at codespeak.net Mon Mar 15 18:23:18 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 15 Mar 2010 18:23:18 +0100 (CET) Subject: [pypy-svn] r72257 - pypy/trunk/lib-python/modified-2.5.2/distutils Message-ID: <20100315172318.DFDCD282B9C@codespeak.net> Author: fijal Date: Mon Mar 15 18:23:17 2010 New Revision: 72257 Modified: pypy/trunk/lib-python/modified-2.5.2/distutils/sysconfig_pypy.py Log: Add a dummy customize compiler. For whatever reasons it makes stuff easy_install instead of exploding. Modified: pypy/trunk/lib-python/modified-2.5.2/distutils/sysconfig_pypy.py ============================================================================== --- pypy/trunk/lib-python/modified-2.5.2/distutils/sysconfig_pypy.py (original) +++ pypy/trunk/lib-python/modified-2.5.2/distutils/sysconfig_pypy.py Mon Mar 15 18:23:17 2010 @@ -93,3 +93,9 @@ get_config_vars().get(name) """ return get_config_vars().get(name) + +def customize_compiler(options): + """Dummy method to let some easy_install packages that have + optional C speedup components. + """ + pass From magcius at codespeak.net Mon Mar 15 20:18:01 2010 From: magcius at codespeak.net (magcius at codespeak.net) Date: Mon, 15 Mar 2010 20:18:01 +0100 (CET) Subject: [pypy-svn] r72258 - pypy/branch/avm/pypy/translator/avm2 Message-ID: <20100315191801.B7789282B9C@codespeak.net> Author: magcius Date: Mon Mar 15 20:17:59 2010 New Revision: 72258 Added: pypy/branch/avm/pypy/translator/avm2/entrypoint.py (contents, props changed) Log: I forgot to add a file. Added: pypy/branch/avm/pypy/translator/avm2/entrypoint.py ============================================================================== --- (empty file) +++ pypy/branch/avm/pypy/translator/avm2/entrypoint.py Mon Mar 15 20:17:59 2010 @@ -0,0 +1,64 @@ + +from pypy.translator.avm2.types_ import Avm2TypeSystem +from pypy.translator.avm2.database import LowLevelDatabase +from pypy.translator.cli.node import Node +from pypy.rpython.ootypesystem import ootype + +def get_entrypoint(graph): + from pypy.translator.avm2.test.runtest import TestEntryPoint + try: + ARG0 = graph.getargs()[0].concretetype + except IndexError: + ARG0 = None + if isinstance(ARG0, ootype.List) and ARG0.ITEM is ootype.String: + return StandaloneEntryPoint(graph) + else: + return TestEntryPoint(graph) + +class BaseEntryPoint(Node): + + def set_db(self, db): + self.db = db + self.cts = Avm2TypeSystem(db) + +class StandaloneEntryPoint(BaseEntryPoint): + """ + This class produces a 'main' method that converts the argv in a + List of Strings and pass it to the real entry point. + """ + + def __init__(self, graph_to_call): + self.graph = graph_to_call + + def get_name(self): + return 'main' + + def render(self, ilasm): + try: + ARG0 = self.graph.getargs()[0].concretetype + except IndexError: + ARG0 = None + assert isinstance(ARG0, ootype.List) and ARG0.ITEM is ootype.String,\ + 'Wrong entry point signature: List(String) expected' + + qname = self.cts.graph_to_qname(self.graph) + ilasm.emit('findpropstrict', qname) + ilasm.emit('callpropvoid', qname, 0) + ## ilasm.opcode('pop') # XXX: return this value, if it's an int32 + + ## ilasm.call('void [pypylib]pypy.runtime.DebugPrint::close_file()') + ## ilasm.opcode('ret') + ## ilasm.end_function() + self.db.pending_function(self.graph) + +class LibraryEntryPoint(BaseEntryPoint): + def __init__(self, name, graphs): + self.name = name + self.graphs = graphs + + def get_name(self): + return self.name + + def render(self, ilasm): + for graph in self.graphs: + self.db.pending_function(graph) From arigo at codespeak.net Mon Mar 15 20:32:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 15 Mar 2010 20:32:35 +0100 (CET) Subject: [pypy-svn] r72259 - in pypy/trunk/pypy/jit/backend: llsupport x86 x86/test Message-ID: <20100315193235.C46A9282B9C@codespeak.net> Author: arigo Date: Mon Mar 15 20:32:33 2010 New Revision: 72259 Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py Log: Write a test, which I think is finally failing for the reason I expect. Document this reason as an XXX is assembler.py. Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Mon Mar 15 20:32:33 2010 @@ -325,6 +325,7 @@ class GcLLDescr_framework(GcLLDescription): + DEBUG = False # forced to True by x86/test/test_zrpy_gc.py def __init__(self, gcdescr, translator, llop1=llop): from pypy.rpython.memory.gctypelayout import _check_typeid @@ -436,7 +437,21 @@ self.malloc_unicode = malloc_unicode self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType( [lltype.Signed], llmemory.GCREF)) + # + class ForTestOnly: + pass + for_test_only = ForTestOnly() + for_test_only.x = 1.23 + def random_usage_of_xmm_registers(): + x0 = for_test_only.x + x1 = x0 * 0.1 + x2 = x0 * 0.2 + x3 = x0 * 0.3 + for_test_only.x = x0 + x1 + x2 + x3 + # def malloc_fixedsize_slowpath(size): + if self.DEBUG: + random_usage_of_xmm_registers() try: gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, 0, size, True, False, False) Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Mon Mar 15 20:32:33 2010 @@ -1244,7 +1244,8 @@ # as pushed above, plus optionally in esi[-16] to esi[-1] for # the XMM registers. Moreover, esi[8] is a pointer to the recovery # bytecode, pushed just before by the CALL instruction written by - # generate_quick_failure(). + # generate_quick_failure(). XXX misaligned stack in the call, but + # it's ok because failure_recovery_func is not calling anything more mc.PUSH(esi) mc.CALL(rel32(failure_recovery_func)) # returns in eax the fail_index @@ -1395,6 +1396,9 @@ # we choose the most compact encoding over the most efficient one. for i in range(len(arglocs)-1, -1, -1): mc.PUSH(arglocs[i]) + # misaligned stack in the call, but it's ok because the write barrier + # is not going to call anything more. Also, this assumes that the + # write barrier does not touch the xmm registers. mc.CALL(rel32(descr.get_write_barrier_fn(self.cpu))) for i in range(len(arglocs)): loc = arglocs[i] @@ -1446,6 +1450,7 @@ mc.CMP(edx, heap(nursery_top_adr)) mc.write(constlistofchars('\x76\x00')) # JNA after the block jmp_adr = mc.get_relative_pos() + # XXXXXXXXXXXXXXXX must save and restore xmm registers here!!!! self._emit_call(rel32(slowpath_addr), [imm(size)], force_mc=True, mc=mc) Modified: pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_zrpy_gc.py Mon Mar 15 20:32:33 2010 @@ -12,9 +12,10 @@ from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.jit import JitDriver, OPTIMIZER_SIMPLE, dont_look_inside -from pypy.rlib.jit import purefunction +from pypy.rlib.jit import purefunction, unroll_safe from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.llsupport.gc import GcRefList, GcRootMap_asmgcc +from pypy.jit.backend.llsupport.gc import GcLLDescr_framework from pypy.tool.udir import udir class X(object): @@ -162,7 +163,13 @@ 'x5', 'x6', 'x7', 'l', 's']) cls.main_allfuncs = staticmethod(main_allfuncs) cls.name_to_func = name_to_func - cls.cbuilder = compile(get_entry(allfuncs), "hybrid", gcrootfinder="asmgcc", jit=True) + OLD_DEBUG = GcLLDescr_framework.DEBUG + try: + GcLLDescr_framework.DEBUG = True + cls.cbuilder = compile(get_entry(allfuncs), "hybrid", + gcrootfinder="asmgcc", jit=True) + finally: + GcLLDescr_framework.DEBUG = OLD_DEBUG def run(self, name, n=2000): pypylog = udir.join('TestCompileHybrid.log') @@ -455,3 +462,53 @@ def test_compile_hybrid_vref(self): self.run('compile_hybrid_vref', 200) + + def define_compile_hybrid_float(self): + # test for a bug: the fastpath_malloc does not save and restore + # xmm registers around the actual call to the slow path + class A: + x0 = x1 = x2 = x3 = x4 = x5 = x6 = x7 = 0 + @dont_look_inside + def escape1(a): + a.x0 += 0 + a.x1 += 6 + a.x2 += 12 + a.x3 += 18 + a.x4 += 24 + a.x5 += 30 + a.x6 += 36 + a.x7 += 42 + @dont_look_inside + def escape2(n, f0, f1, f2, f3, f4, f5, f6, f7): + check(f0 == n + 0.0) + check(f1 == n + 0.125) + check(f2 == n + 0.25) + check(f3 == n + 0.375) + check(f4 == n + 0.5) + check(f5 == n + 0.625) + check(f6 == n + 0.75) + check(f7 == n + 0.875) + @unroll_safe + def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s): + i = 0 + while i < 42: + m = n + i + f0 = m + 0.0 + f1 = m + 0.125 + f2 = m + 0.25 + f3 = m + 0.375 + f4 = m + 0.5 + f5 = m + 0.625 + f6 = m + 0.75 + f7 = m + 0.875 + a1 = A() + # at this point, all or most f's are still in xmm registers + escape1(a1) + escape2(m, f0, f1, f2, f3, f4, f5, f6, f7) + i += 1 + n -= 1 + return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s + return None, f, None + + def test_compile_hybrid_float(self): + self.run('compile_hybrid_float') From magcius at codespeak.net Mon Mar 15 21:05:40 2010 From: magcius at codespeak.net (magcius at codespeak.net) Date: Mon, 15 Mar 2010 21:05:40 +0100 (CET) Subject: [pypy-svn] r72260 - in pypy/branch/avm/pypy/translator/avm2: . test Message-ID: <20100315200540.7BC14282B9C@codespeak.net> Author: magcius Date: Mon Mar 15 21:05:19 2010 New Revision: 72260 Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py Log: More work on the AVM2 translator Modified: pypy/branch/avm/pypy/translator/avm2/avm2gen.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/avm2gen.py (original) +++ pypy/branch/avm/pypy/translator/avm2/avm2gen.py Mon Mar 15 21:05:19 2010 @@ -27,7 +27,7 @@ def _get_type(self, TYPE): return self.cts.lltype_to_cts(TYPE) - def get_class_context(self, name, DICT): + def _get_class_context(self, name, DICT): class_desc = query.get_class_desc(name) if class_desc: BaseType = class_desc.BaseType Modified: pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py ============================================================================== --- pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py (original) +++ pypy/branch/avm/pypy/translator/avm2/test/entrypoint.py Mon Mar 15 21:05:19 2010 @@ -82,15 +82,8 @@ self.actions.finish() def do_test(self): - self.finish_test() - f = open("%s.swf" % (self.name,), "wb") - f.write(self.swf.serialize()) - f.close() - f = open("%s.abc" % (self.name,), "wb") - f.write(self.abc.serialize()) - f.close() - return browsertest(self.name, self.swf) - + pass + def epilogue(self): pass @@ -98,6 +91,16 @@ pass class SWFTestEntryPoint(BaseTestEntryPoint): + def do_test(self): + self.finish_test() + f = open("%s.flash.swf" % (self.name,), "wb") + f.write(self.swf.serialize()) + f.close() + f = open("%s.flash.abc" % (self.name,), "wb") + f.write(self.abc.serialize()) + f.close() + return browsertest(self.name, self.swf) + def get_edittext(self): if not self.actions.HL('edittext'): self.actions.push_this() @@ -144,6 +147,12 @@ self.actions.emit('callpropvoid', packagedQName("flash.net", "navigateToURL"), 2) class TamarinTestEntryPoint(BaseTestEntryPoint): + def do_test(self): + f = open("%s.tamarin.abc" % (self.name,), "wb") + f.write(self.abc.serialize()) + f.close() + asdf + def update_text(self): self.actions.push_const("\n") self.actions.get_field('text') @@ -153,6 +162,7 @@ def epilogue(self): self.actions.exit_until_type("script") + self.actions.context.make_init() self.actions.push_var('this') self.actions.emit('constructprop', QName("PyPyTest_EntryPoint"), 0) From cfbolz at codespeak.net Mon Mar 15 21:09:06 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 15 Mar 2010 21:09:06 +0100 (CET) Subject: [pypy-svn] r72261 - pypy/trunk/pypy/jit/metainterp/test Message-ID: <20100315200906.62615282B9C@codespeak.net> Author: cfbolz Date: Mon Mar 15 21:08:43 2010 New Revision: 72261 Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Log: a failing test for revision 71300. No clue how to fix that. Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original) +++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Mon Mar 15 21:08:43 2010 @@ -1740,6 +1740,29 @@ self.optimize_loop(ops, 'Not, VArray(arraydescr2, Not)', expected) + @py.test.mark.xfail + def test_bug_3(self): + ops = """ + [p1] + guard_nonnull(p1) [] + guard_class(p1, ConstClass(node_vtable2)) [] + p2 = getfield_gc(p1, descr=nextdescr) + guard_nonnull(12) [] + guard_class(p2, ConstClass(node_vtable)) [] + p3 = getfield_gc(p1, descr=otherdescr) + guard_nonnull(12) [] + guard_class(p3, ConstClass(node_vtable)) [] + setfield_gc(p3, p2, descr=otherdescr) + p1a = new_with_vtable(ConstClass(node_vtable2)) + p2a = new_with_vtable(ConstClass(node_vtable)) + p3a = new_with_vtable(ConstClass(node_vtable)) + escape(p3a) + setfield_gc(p1a, p2a, descr=nextdescr) + setfield_gc(p1a, p3a, descr=otherdescr) + jump(p1a) + """ + self.optimize_loop(ops, 'Virtual(node_vtable2, nextdescr=Virtual(node_vtable), otherdescr=Not)', None) + def test_invalid_loop_1(self): ops = """ [p1] From cfbolz at codespeak.net Mon Mar 15 21:13:30 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 15 Mar 2010 21:13:30 +0100 (CET) Subject: [pypy-svn] r72262 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100315201330.4415E282B9C@codespeak.net> Author: cfbolz Date: Mon Mar 15 21:13:02 2010 New Revision: 72262 Added: pypy/trunk/pypy/jit/metainterp/viewnode.py (contents, props changed) Modified: pypy/trunk/pypy/jit/metainterp/optimizefindnode.py Log: Visualization of optimizefindnode nodes with graphviz. Modified: pypy/trunk/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizefindnode.py Mon Mar 15 21:13:02 2010 @@ -314,10 +314,21 @@ node_fromstart = InstanceNode(fromstart=True) def find_nodes_loop(self, loop): + self._loop = loop self.setup_input_nodes(loop.inputargs) self.find_nodes(loop.operations) self.build_result_specnodes(loop) + def show(self): + from pypy.jit.metainterp.viewnode import viewnodes, view + op = self._loop.operations[-1] + assert op.opnum == rop.JUMP + exitnodes = [self.getnode(arg) for arg in op.args] + viewnodes(self.inputnodes, exitnodes) + if hasattr(self._loop.token, "specnodes"): + view(self._loop.token.specnodes) + + def setup_input_nodes(self, inputargs): inputnodes = [] for box in inputargs: Added: pypy/trunk/pypy/jit/metainterp/viewnode.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/jit/metainterp/viewnode.py Mon Mar 15 21:13:02 2010 @@ -0,0 +1,124 @@ +import py +from pypy.jit.metainterp import specnode, optimizefindnode +from pypy.tool.pairtype import extendabletype + +class __extend__(specnode.NotSpecNode): + def _dot(self, seen): + if self in seen: + return + seen.add(self) + yield '%s [label=""]' % (id(self), ) + +class __extend__(specnode.ConstantSpecNode): + def _dot(self, seen): + if self in seen: + return + seen.add(self) + yield '%s [label=""]' % (id(self), self.constbox) + +class __extend__(specnode.AbstractVirtualStructSpecNode): + def _dot(self, seen): + if self in seen: + return + seen.add(self) + yield '%s [label="<%s>"]' % ( + id(self), + self.__class__.__name__[:-len("SpecNode")]) + for label, node in self.fields: + yield '%s -> %s [label="%s"]' % (id(self), id(node), label.name) + for line in node._dot(seen): + yield line + +class __extend__(specnode.VirtualArraySpecNode): + def _dot(self, seen): + if self in seen: + return + seen.add(self) + yield '%s [label=""]' % ( + id(self), + len(self.items)) + for i, node in enumerate(self.items): + yield '%s -> %s [label="%s"]' % (id(self), id(node), i) + for line in node._dot(seen): + yield line + + +class __extend__(optimizefindnode.InstanceNode): + __metaclass__ = extendabletype # evil + + def _dot(self, seen): + if self in seen: + return + seen.add(self) + if self.knownclsbox: + name = "Virtual " + if isinstance(self.knownclsbox.value, int): + name += str(self.knownclsbox.value) + else: + name += str(self.knownclsbox.value.ptr).rpartition("_vtable")[0].rpartition('.')[2] + elif self.structdescr: + name = "Struct " + str(self.structdescr) + elif self.arraydescr: + name = "Array" + else: + name = "Not" + if self.escaped: + name = "ESC " + name + if self.fromstart: + name = "START " + name + if self.unique == optimizefindnode.UNIQUE_NO: + color = "blue" + else: + color = "black" + + yield 'orig%s [label="in: [%s]", shape=box, color=%s]' % ( + id(self), name, color) + yield '%s [label="out: [%s]", shape=box, color=%s]' % ( + id(self), name, color) + yield 'orig%s -> %s [color=red]' % (id(self), id(self)) + if self.origfields: + for descr, node in self.origfields.iteritems(): + yield 'orig%s -> orig%s [label="%s"]' % (id(self), id(node), descr.name) + for line in node._dot(seen): + yield line + if self.curfields: + for descr, node in self.curfields.iteritems(): + yield '%s -> %s [label="%s"]' % (id(self), id(node), descr.name) + for line in node._dot(seen): + yield line + if self.origitems: + for i, node in sorted(self.origitems.iteritems()): + yield 'orig%s -> orig%s [label="%s"]' % (id(self), id(node), i) + for line in node._dot(seen): + yield line + if self.curitems: + for i, node in sorted(self.curitems.iteritems()): + yield '%s -> %s [label="%s"]' % (id(self), id(node), i) + for line in node._dot(seen): + yield line + + +def view(*objects): + from dotviewer import graphclient + content = ["digraph G{"] + seen = set() + for obj in objects: + content.extend(obj._dot(seen)) + content.append("}") + p = py.test.ensuretemp("specnodes").join("temp.dot") + p.write("\n".join(content)) + graphclient.display_dot_file(str(p)) + +def viewnodes(l1, l2): + from dotviewer import graphclient + content = ["digraph G{"] + seen = set() + for obj in l1 + l2: + content.extend(obj._dot(seen)) + for i, (o1, o2) in enumerate(zip(l1, l2)): + content.append("%s -> %s [color=green]" % (id(o1), i)) + content.append("%s -> orig%s [color=green]" % (i, id(o2))) + content.append("}") + p = py.test.ensuretemp("specnodes").join("temp.dot") + p.write("\n".join(content)) + graphclient.display_dot_file(str(p)) From arigo at codespeak.net Mon Mar 15 22:57:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 15 Mar 2010 22:57:27 +0100 (CET) Subject: [pypy-svn] r72263 - in pypy/trunk/pypy: jit/backend/llsupport jit/backend/x86 jit/backend/x86/test translator/c Message-ID: <20100315215727.2E4C6282B90@codespeak.net> Author: arigo Date: Mon Mar 15 22:57:25 2010 New Revision: 72263 Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py pypy/trunk/pypy/translator/c/genc.py Log: Fix the bug of r72259. Simplifies a bit stuff (no more longlong result) at the cost of a more complicated, but local, hack in assembler.py. Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Mon Mar 15 22:57:25 2010 @@ -14,7 +14,6 @@ from pypy.jit.backend.llsupport.descr import GcCache, get_field_descr from pypy.jit.backend.llsupport.descr import GcPtrFieldDescr from pypy.jit.backend.llsupport.descr import get_call_descr -from pypy.rlib.rarithmetic import r_ulonglong, r_uint # ____________________________________________________________ @@ -457,13 +456,11 @@ 0, size, True, False, False) except MemoryError: fatalerror("out of memory (from JITted code)") - return r_ulonglong(0) - res = rffi.cast(lltype.Signed, gcref) - nurs_free = llop1.gc_adr_of_nursery_free(llmemory.Address).signed[0] - return r_ulonglong(nurs_free) << 32 | r_ulonglong(r_uint(res)) + return 0 + return rffi.cast(lltype.Signed, gcref) self.malloc_fixedsize_slowpath = malloc_fixedsize_slowpath self.MALLOC_FIXEDSIZE_SLOWPATH = lltype.FuncType([lltype.Signed], - lltype.UnsignedLongLong) + lltype.Signed) def get_nursery_free_addr(self): nurs_addr = llop.gc_adr_of_nursery_free(llmemory.Address) Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Mon Mar 15 22:57:25 2010 @@ -118,6 +118,8 @@ self.fail_ebp = 0 self.loc_float_const_neg = None self.loc_float_const_abs = None + self.malloc_fixedsize_slowpath1 = 0 + self.malloc_fixedsize_slowpath2 = 0 self.setup_failure_recovery() def leave_jitted_hook(self): @@ -164,6 +166,8 @@ self._build_failure_recovery(True, withfloats=True) codebuf.ensure_sse2_floats() self._build_float_constants() + if hasattr(gc_ll_descr, 'get_malloc_fixedsize_slowpath_addr'): + self._build_malloc_fixedsize_slowpath() def _build_float_constants(self): # 11 words: 8 words for the data, and up to 3 words for alignment @@ -184,6 +188,27 @@ self.loc_float_const_neg = heap64(float_constants) self.loc_float_const_abs = heap64(float_constants + 16) + def _build_malloc_fixedsize_slowpath(self): + mc = self.mc2._mc + # ---------- first helper for the slow path of malloc ---------- + self.malloc_fixedsize_slowpath1 = mc.tell() + if self.cpu.supports_floats: # save the XMM registers in + for i in range(8): # the *caller* frame, from esp+8 + mc.MOVSD(mem64(esp, 8+8*i), xmm_registers[i]) + mc.SUB(edx, eax) # compute the size we want + mc.MOV(mem(esp, 4), edx) # save it as the new argument + addr = self.cpu.gc_ll_descr.get_malloc_fixedsize_slowpath_addr() + mc.JMP(rel32(addr)) # tail call to the real malloc + # ---------- second helper for the slow path of malloc ---------- + self.malloc_fixedsize_slowpath2 = mc.tell() + if self.cpu.supports_floats: # restore the XMM registers + for i in range(8): # from where they were saved + mc.MOVSD(xmm_registers[i], mem64(esp, 8+8*i)) + nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() + mc.MOV(edx, heap(nursery_free_adr)) # load this in EDX + mc.RET() + self.mc2.done() + def assemble_loop(self, inputargs, operations, looptoken): """adds the following attributes to looptoken: _x86_loop_code (an integer giving an address) @@ -1442,7 +1467,7 @@ self.mc.JMP(rel32(loop_token._x86_loop_code)) def malloc_cond_fixedsize(self, nursery_free_adr, nursery_top_adr, - size, tid, slowpath_addr): + size, tid): # don't use self.mc mc = self._start_block() mc.MOV(eax, heap(nursery_free_adr)) @@ -1450,14 +1475,25 @@ mc.CMP(edx, heap(nursery_top_adr)) mc.write(constlistofchars('\x76\x00')) # JNA after the block jmp_adr = mc.get_relative_pos() - # XXXXXXXXXXXXXXXX must save and restore xmm registers here!!!! - self._emit_call(rel32(slowpath_addr), [imm(size)], - force_mc=True, mc=mc) - - # note that slowpath_addr returns a "long long", or more precisely - # two results, which end up in eax and edx. - # eax should contain the result of allocation, edx new value - # of nursery_free_adr + + # See comments in _build_malloc_fixedsize_slowpath for the + # details of the two helper functions that we are calling below. + # First, we need to call two of them and not just one because we + # need to have a mark_gc_roots() in between. Then the calling + # convention of slowpath_addr{1,2} are tweaked a lot to allow + # the code here to be just two CALLs: slowpath_addr1 gets the + # size of the object to allocate from (EDX-EAX) and returns the + # result in EAX; slowpath_addr2 additionally returns in EDX a + # copy of heap(nursery_free_adr), so that the final MOV below is + # a no-op. + slowpath_addr1 = self.malloc_fixedsize_slowpath1 + # reserve room for the argument to the real malloc and the + # 8 saved XMM regs + self._regalloc.reserve_param(1+16) + mc.CALL(rel32(slowpath_addr1)) + self.mark_gc_roots() + slowpath_addr2 = self.malloc_fixedsize_slowpath2 + mc.CALL(rel32(slowpath_addr2)) offset = mc.get_relative_pos() - jmp_adr assert 0 < offset <= 127 Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Mon Mar 15 22:57:25 2010 @@ -702,7 +702,6 @@ gc_ll_descr.get_nursery_free_addr(), gc_ll_descr.get_nursery_top_addr(), descr.size, descr.tid, - gc_ll_descr.get_malloc_fixedsize_slowpath_addr(), ) def consider_new(self, op): Modified: pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py Mon Mar 15 22:57:25 2010 @@ -175,15 +175,13 @@ self.addrs[1] = self.addrs[0] + 64 # 64 bytes def malloc_slowpath(size): - from pypy.rlib.rarithmetic import r_ulonglong assert size == 8 nadr = rffi.cast(lltype.Signed, self.nursery) - self.addrs[0] = 99999 # should be overridden by the caller - return ((r_ulonglong(nadr + size) << 32) | # this part in edx - r_ulonglong(nadr)) # this part in eax + self.addrs[0] = nadr + size + return nadr self.malloc_slowpath = malloc_slowpath self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed], - lltype.UnsignedLongLong) + lltype.Signed) self._counter = 123 def can_inline_malloc(self, descr): Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Mon Mar 15 22:57:25 2010 @@ -437,6 +437,7 @@ if res.returncode != 0: if expect_crash: return res.out, res.err + print >> sys.stderr, res.err raise Exception("Returned %d" % (res.returncode,)) if expect_crash: raise Exception("Program did not crash!") From mwh at codespeak.net Tue Mar 16 04:54:27 2010 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 16 Mar 2010 04:54:27 +0100 (CET) Subject: [pypy-svn] r72264 - pypy/trunk/pypy/doc/jit Message-ID: <20100316035427.6C86F282B90@codespeak.net> Author: mwh Date: Tue Mar 16 04:54:23 2010 New Revision: 72264 Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt Log: typo Modified: pypy/trunk/pypy/doc/jit/pyjitpl5.txt ============================================================================== --- pypy/trunk/pypy/doc/jit/pyjitpl5.txt (original) +++ pypy/trunk/pypy/doc/jit/pyjitpl5.txt Tue Mar 16 04:54:23 2010 @@ -82,7 +82,7 @@ *Tracing* is where JIT interprets the bytecode, generated at translation time, of the interpreter interpreting the application level code. This allows it to see the exact operations that make up the application level loop. Tracing is -preformed by MetaInterp and MIFrame classes in metainterp/pyjitpl.py. +performed by MetaInterp and MIFrame classes in metainterp/pyjitpl.py. maybe_compile_and_run() creates a MetaInterp and calls its compile_and_run_once() method. This initializes the MIFrame for the input arguments of the loop, the red and green variables passed from the From fijal at codespeak.net Tue Mar 16 05:08:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 16 Mar 2010 05:08:39 +0100 (CET) Subject: [pypy-svn] r72265 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100316040839.8217A282B90@codespeak.net> Author: fijal Date: Tue Mar 16 05:08:38 2010 New Revision: 72265 Added: pypy/extradoc/talk/oopsla2010/paper.txt (contents, props changed) Log: Start writing down stuff, a complete crap so far Added: pypy/extradoc/talk/oopsla2010/paper.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/oopsla2010/paper.txt Tue Mar 16 05:08:38 2010 @@ -0,0 +1,23 @@ +Problem domain +============== + +Python (and other dynamic languages, to varying extent) has a frame +introspection capabilities built in language. This means that at any +given point in time, python code can request the list of local variables +or introspect what functions are on the stack. Due to the dynamic nature of +python, such checks are usually impossible to detect statically. In Python +you can overload all operations, so checking length of an object or decoding +unicode or innocent addition can call a piece of arbitrary python code. + +XXX write down why we can't exactly keep the frame on the C stack and +XXX use an API to manipulate that. I'm not sure if it's really the problem +XXX since we do the same on assembler stack + +Approach +======== + +In the previous paper we discussed the tracing infrastructure that allows +us to implement an efficient tracing JIT for interpreters, good enough +to scale to python interpreter. In this paper we will discuss how do +we deal with frame objects and how we chain frame objects in a way +that removes most costs associated with them. From fijal at codespeak.net Tue Mar 16 05:18:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 16 Mar 2010 05:18:52 +0100 (CET) Subject: [pypy-svn] r72266 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100316041852.BB42D282B90@codespeak.net> Author: fijal Date: Tue Mar 16 05:18:51 2010 New Revision: 72266 Modified: pypy/extradoc/talk/oopsla2010/paper.txt Log: Write something down today Modified: pypy/extradoc/talk/oopsla2010/paper.txt ============================================================================== --- pypy/extradoc/talk/oopsla2010/paper.txt (original) +++ pypy/extradoc/talk/oopsla2010/paper.txt Tue Mar 16 05:18:51 2010 @@ -21,3 +21,17 @@ to scale to python interpreter. In this paper we will discuss how do we deal with frame objects and how we chain frame objects in a way that removes most costs associated with them. + +We remove frame overhead in a two different ways, depending on the place +in trace where function call happens: + +1. For the outermost function within the compiled loop (XXX trace, can be + something else as far as I remember), we use objects called *virtualizables*, + which are allocated, but who's fields are ... (XXX write down how they're + lazily accessed from the other places and not at all from the JIT) + +2. For inlined functions, the frames are known not to escape, which + means we don't need to allocate them at all, but ... + +3. We have to maintain a frame chain via special objects called virtualrefs + XXX explain From cfbolz at codespeak.net Tue Mar 16 10:15:15 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 16 Mar 2010 10:15:15 +0100 (CET) Subject: [pypy-svn] r72267 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100316091515.1DA9A282B9E@codespeak.net> Author: cfbolz Date: Tue Mar 16 10:15:13 2010 New Revision: 72267 Modified: pypy/trunk/pypy/jit/metainterp/optimizefindnode.py Log: typo Modified: pypy/trunk/pypy/jit/metainterp/optimizefindnode.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/optimizefindnode.py (original) +++ pypy/trunk/pypy/jit/metainterp/optimizefindnode.py Tue Mar 16 10:15:13 2010 @@ -326,7 +326,7 @@ exitnodes = [self.getnode(arg) for arg in op.args] viewnodes(self.inputnodes, exitnodes) if hasattr(self._loop.token, "specnodes"): - view(self._loop.token.specnodes) + view(*self._loop.token.specnodes) def setup_input_nodes(self, inputargs): From arigo at codespeak.net Tue Mar 16 10:33:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 10:33:04 +0100 (CET) Subject: [pypy-svn] r72268 - in pypy/trunk/pypy/jit/backend: . test Message-ID: <20100316093304.A951F282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 10:33:03 2010 New Revision: 72268 Added: pypy/trunk/pypy/jit/backend/test/test_detect_cpu.py (contents, props changed) Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py Log: A refactoring and a test for detect_cpu. Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py ============================================================================== --- pypy/trunk/pypy/jit/backend/detect_cpu.py (original) +++ pypy/trunk/pypy/jit/backend/detect_cpu.py Tue Mar 16 10:33:03 2010 @@ -49,20 +49,25 @@ model = 'x86-without-sse2' return model -def getcpuclass(backend_name="auto"): +def getcpuclassname(backend_name="auto"): if backend_name == "auto": backend_name = autodetect() if backend_name in ('i386', 'x86'): - from pypy.jit.backend.x86.runner import CPU + return "pypy.jit.backend.x86.runner", "CPU" elif backend_name == 'x86-without-sse2': - from pypy.jit.backend.x86.runner import CPU386_NO_SSE2 as CPU + return "pypy.jit.backend.x86.runner", "CPU386_NO_SSE2" elif backend_name == 'cli': - from pypy.jit.backend.cli.runner import CliCPU as CPU + return "pypy.jit.backend.cli.runner", "CliCPU" elif backend_name == 'llvm': - from pypy.jit.backend.llvm.runner import LLVMCPU as CPU + return "pypy.jit.backend.llvm.runner", "LLVMCPU" else: raise ProcessorAutodetectError, "unsupported cpu '%s'" % backend_name - return CPU + +def getcpuclass(backend_name="auto"): + modname, clsname = getcpuclassname(backend_name) + mod = __import__(modname, {}, {}, clsname) + return getattr(mod, clsname) if __name__ == '__main__': print autodetect() + print getcpuclassname() Added: pypy/trunk/pypy/jit/backend/test/test_detect_cpu.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/jit/backend/test/test_detect_cpu.py Tue Mar 16 10:33:03 2010 @@ -0,0 +1,28 @@ +from pypy.jit.backend.detect_cpu import * + + +def test_autodetect(): + try: + name = autodetect() + except ProcessorAutodetectError: + pass + else: + assert isinstance(name, str) + +def test_getcpuclassname(): + try: + modname, clsname = getcpuclassname() + except ProcessorAutodetectError: + pass + else: + assert isinstance(modname, str) + assert isinstance(clsname, str) + +def test_getcpuclass(): + try: + cpu = getcpuclass() + except ProcessorAutodetectError: + pass + else: + from pypy.jit.backend.model import AbstractCPU + assert issubclass(cpu, AbstractCPU) From arigo at codespeak.net Tue Mar 16 10:37:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 10:37:31 +0100 (CET) Subject: [pypy-svn] r72269 - pypy/trunk/pypy/translator/goal Message-ID: <20100316093731.12445282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 10:37:29 2010 New Revision: 72269 Modified: pypy/trunk/pypy/translator/goal/translate.py Log: issue493 resolved Modified: pypy/trunk/pypy/translator/goal/translate.py ============================================================================== --- pypy/trunk/pypy/translator/goal/translate.py (original) +++ pypy/trunk/pypy/translator/goal/translate.py Tue Mar 16 10:37:29 2010 @@ -264,6 +264,10 @@ if (translateconfig.goals != ['annotate'] and translateconfig.goals != ['rtype']): drv.set_extra_goals(['pyjitpl']) + # early check: + from pypy.jit.backend.detect_cpu import getcpuclassname + getcpuclassname(config.translation.jit_backend) + log_config(config.translation, "translation configuration") pdb_plus_show.expose({'drv': drv, 'prof': prof}) From arigo at codespeak.net Tue Mar 16 10:39:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 10:39:29 +0100 (CET) Subject: [pypy-svn] r72270 - pypy/trunk/pypy/jit/backend Message-ID: <20100316093929.B0E24282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 10:39:28 2010 New Revision: 72270 Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py Log: Improve the error message. Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py ============================================================================== --- pypy/trunk/pypy/jit/backend/detect_cpu.py (original) +++ pypy/trunk/pypy/jit/backend/detect_cpu.py Tue Mar 16 10:39:28 2010 @@ -61,7 +61,8 @@ elif backend_name == 'llvm': return "pypy.jit.backend.llvm.runner", "LLVMCPU" else: - raise ProcessorAutodetectError, "unsupported cpu '%s'" % backend_name + raise ProcessorAutodetectError, ( + "we have no JIT backend for this cpu: '%s'" % backend_name) def getcpuclass(backend_name="auto"): modname, clsname = getcpuclassname(backend_name) From arigo at codespeak.net Tue Mar 16 10:51:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 10:51:51 +0100 (CET) Subject: [pypy-svn] r72271 - in pypy/trunk/pypy/jit/backend: . x86/test Message-ID: <20100316095151.C52B7282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 10:51:50 2010 New Revision: 72271 Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py pypy/trunk/pypy/jit/backend/x86/test/conftest.py Log: Always return 'x86' instead of sometimes 'i386' and sometimes 'x86'. Modified: pypy/trunk/pypy/jit/backend/detect_cpu.py ============================================================================== --- pypy/trunk/pypy/jit/backend/detect_cpu.py (original) +++ pypy/trunk/pypy/jit/backend/detect_cpu.py Tue Mar 16 10:51:50 2010 @@ -18,7 +18,7 @@ if not mach: platform = sys.platform.lower() if platform.startswith('win'): # assume an Intel Windows - return 'i386' + return 'x86' # assume we have 'uname' mach = os.popen('uname -m', 'r').read().strip() if not mach: @@ -29,12 +29,12 @@ else: assert sys.maxint == 2 ** 63 - 1 try: - return {'i386': 'i386', - 'i486': 'i386', - 'i586': 'i386', - 'i686': 'i386', - 'i86pc': 'i386', # Solaris/Intel - 'x86': 'i386', # Apple + return {'i386': 'x86', + 'i486': 'x86', + 'i586': 'x86', + 'i686': 'x86', + 'i86pc': 'x86', # Solaris/Intel + 'x86': 'x86', # Apple 'Power Macintosh': 'ppc', 'x86_64': 'x86_64', }[mach] @@ -43,7 +43,7 @@ def autodetect(): model = autodetect_main_model() - if model in ('i386', 'x86'): + if model == 'x86': from pypy.jit.backend.x86.detect_sse2 import detect_sse2 if not detect_sse2(): model = 'x86-without-sse2' @@ -52,7 +52,7 @@ def getcpuclassname(backend_name="auto"): if backend_name == "auto": backend_name = autodetect() - if backend_name in ('i386', 'x86'): + if backend_name == 'x86': return "pypy.jit.backend.x86.runner", "CPU" elif backend_name == 'x86-without-sse2': return "pypy.jit.backend.x86.runner", "CPU386_NO_SSE2" Modified: pypy/trunk/pypy/jit/backend/x86/test/conftest.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/conftest.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/conftest.py Tue Mar 16 10:51:50 2010 @@ -4,6 +4,6 @@ class Directory(py.test.collect.Directory): def collect(self): cpu = detect_cpu.autodetect() - if cpu != 'i386': + if cpu != 'x86': py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) return super(Directory, self).collect() From arigo at codespeak.net Tue Mar 16 12:35:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 12:35:22 +0100 (CET) Subject: [pypy-svn] r72272 - pypy/branch/ll_math Message-ID: <20100316113522.8A5DD282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 12:35:21 2010 New Revision: 72272 Added: pypy/branch/ll_math/ - copied from r72271, pypy/trunk/ Log: A branch, just because I want to do a few checkins. From arigo at codespeak.net Tue Mar 16 12:36:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 12:36:10 +0100 (CET) Subject: [pypy-svn] r72273 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module Message-ID: <20100316113610.C5D98282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 12:36:09 2010 New Revision: 72273 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Log: In-progress. Untested. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Tue Mar 16 12:36:09 2010 @@ -7,108 +7,285 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.rlib.rarithmetic import isinf +from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN -math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE, - sandboxsafe=True) -math_modf = rffi.llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE, - sandboxsafe=True) -math_ldexp = rffi.llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE, - sandboxsafe=True) +if sys.platform[:3] == "win": + eci = ExternalCompilationInfo(libraries=[]) +else: + eci = ExternalCompilationInfo(libraries=['m']) -unary_math_functions = [ - 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' - ] +def llexternal(name, ARGS, RESULT): + return rffi.llexternal(name, ARGS, RESULT, compilation_info=eci, + sandboxsafe=True) + +math_fabs = llexternal('fabs', [rffi.DOUBLE], rffi.DOUBLE) +math_log = llexternal('log', [rffi.DOUBLE], rffi.DOUBLE) +math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE) +math_copysign = llexternal('copysign', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE) +math_modf = llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE) +math_ldexp = llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE) +math_pow = llexternal('pow', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) + +if sys.platform == 'win32': + math_hypot = llexternal('_hypot', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +else: + math_hypot = llexternal('hypot', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) + +# ____________________________________________________________ +# +# Error handling functions + +ERANGE = errno.ERANGE +EDOM = errno.EDOM + +def _error_reset(): + rposix.set_errno(0) + +def _likely_raise(errno, x): + """Call this with errno != 0. It usually raises the proper RPython + exception, but may also just ignore it and return in case of underflow. + """ + assert errno + if errno == ERANGE: + # We consider underflow to not be an error, like CPython. + # On some platforms (Ubuntu/ia64) it seems that errno can be + # set to ERANGE for subnormal results that do *not* underflow + # to zero. So to be safe, we'll ignore ERANGE whenever the + # function result is less than one in absolute value. + if math_fabs(x) < 1.0: + return + raise OverflowError("math range error") + else: + raise ValueError("math domain error") + +# ____________________________________________________________ +# +# Custom implementations + + +def ll_math_atan2(y, x): + """wrapper for atan2 that deals directly with special cases before + delegating to the platform libm for the remaining cases. This + is necessary to get consistent behaviour across platforms. + Windows, FreeBSD and alpha Tru64 are amongst platforms that don't + always follow C99. + """ + if isnan(x) or isnan(y): + return NAN + + if isinf(y): + if isinf(x): + if math_copysign(1.0, x) == 1.0: + # atan2(+-inf, +inf) == +-pi/4 + return math_copysign(0.25 * math.pi, y) + else: + # atan2(+-inf, -inf) == +-pi*3/4 + return math_copysign(0.75 * math.pi, y) + # atan2(+-inf, x) == +-pi/2 for finite x + return math_copysign(0.5 * math.pi, y) + + if isinf(x) or y == 0.0: + if math_copysign(1.0, x) == 1.0: + # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. + return math_copysign(0.0, y) + else: + # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. + return math_copysign(math.pi, y) + + return math_atan2(y, x) + + +# XXX Various platforms (Solaris, OpenBSD) do nonstandard things for log(0), +# log(-ve), log(NaN). For now I'm ignoring this issue as these are a bit +# more marginal platforms for us. -binary_math_functions = [ - 'atan2', 'fmod', 'hypot', 'pow' - ] def ll_math_frexp(x): - exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - try: - _error_reset() - mantissa = math_frexp(x, exp_p) - _check_error(mantissa) - exponent = rffi.cast(lltype.Signed, exp_p[0]) - finally: - lltype.free(exp_p, flavor='raw') + # deal with special cases directly, to sidestep platform differences + if isnan(x) or isinf(x) or not x: + mantissa = x + exponent = 0 + else: + exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + try: + mantissa = math_frexp(x, exp_p) + exponent = rffi.cast(lltype.Signed, exp_p[0]) + finally: + lltype.free(exp_p, flavor='raw') return (mantissa, exponent) + +INT_MAX = int(2**31-1) +INT_MIN = int(-2**31) + +def ll_math_ldexp(x, exp): + if x == 0.0 or isinf(x) or isnan(x): + return x # NaNs, zeros and infinities are returned unchanged + if exp > INT_MAX: + # overflow (64-bit platforms only) + r = math_copysign(INFINITY, x) + errno = ERANGE + elif exp < INT_MIN: + # underflow to +-0 (64-bit platforms only) + r = math_copysign(0.0, x) + errno = 0 + else: + _error_reset() + r = math_ldexp(x, exp) + errno = rposix.get_errno() + if isinf(r): + errno = ERANGE + if errno: + _likely_raise(errno, r) + return r + + def ll_math_modf(x): + # some platforms don't do the right thing for NaNs and + # infinities, so we take care of special cases directly. + if isinf(x): + return (math_copysign(0.0, x), x) + elif isnan(x): + return (x, x) intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw') try: - _error_reset() fracpart = math_modf(x, intpart_p) - _check_error(fracpart) intpart = intpart_p[0] finally: lltype.free(intpart_p, flavor='raw') return (fracpart, intpart) -def ll_math_ldexp(x, exp): - _error_reset() - r = math_ldexp(x, exp) - _check_error(r) - return r -def _error_reset(): - rposix.set_errno(0) +def ll_math_copysign(x, y): + return math_copysign(x, y) # no error checking needed -ERANGE = errno.ERANGE -def _check_error(x): - errno = rposix.get_errno() + +def ll_math_hypot(x, y): + # hypot(x, +/-Inf) returns Inf, even if x is a NaN. if isinf(x): - errno = ERANGE + return math_fabs(x) + if isinf(y): + return math_fabs(y) + + _error_reset() + r = math_hypot(x, y) + errno = rposix.get_errno() + if isnan(r): + if isnan(x) or isnan(y): + errno = 0 + else: + errno = EDOM + elif isinf(r): + if isinf(x) or isnan(x) or isinf(y) or isnan(y): + errno = 0 + else: + errno = ERANGE if errno: - if errno == ERANGE: - if not x: - return # we consider underflow to not be an error, like CPython - raise OverflowError("math range error") + _likely_raise(errno, r) + return r + + +def ll_math_pow(x, y): + # deal directly with IEEE specials, to cope with problems on various + # platforms whose semantics don't exactly match C99 + + if isnan(x): + if y == 0.0: + return 1.0 # NaN**0 = 1 + return x + + elif isnan(y): + if x == 1.0: + return 1.0 # 1**Nan = 1 + return y + + elif isinf(x): + odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0 + if y > 0.0: + if odd_y: + return x + return math_fabs(x) + elif y == 0.0: + return 1.0 + else: # y < 0.0 + if odd_y: + return math_copysign(0.0, x) + return 0.0 + + elif isinf(y): + if math_fabs(x) == 1.0: + return 1.0 + elif y > 0.0 and math_fabs(x) > 1.0: + return y + elif y < 0.0 and math_fabs(x) < 1.0: + if x == 0.0: + raise ValueError("0**-inf: divide by zero") + return -y # result is +inf else: - raise ValueError("math domain error") + return 0.0 -if sys.platform[:3] == "win": - eci = ExternalCompilationInfo(libraries=[]) -else: - eci = ExternalCompilationInfo(libraries=['m']) + _error_reset() + r = math_pow(x, y) + errno = rposix.get_errno() + if isnan(r): + # a NaN result should arise only from (-ve)**(finite non-integer) + errno = EDOM + elif isinf(r): + # an infinite result here arises either from: + # (A) (+/-0.)**negative (-> divide-by-zero) + # (B) overflow of x**y with x and y finite + if x == 0.0: + errno = EDOM + else: + errno = ERANGE + if errno: + _likely_raise(errno, r) + return r +# ____________________________________________________________ +# +# Default implementations -def new_unary_math_function(name): - c_func = rffi.llexternal(name, [rffi.DOUBLE], rffi.DOUBLE, - compilation_info=eci, sandboxsafe=True) +def new_unary_math_function(name, can_overflow): + c_func = llexternal(name, [rffi.DOUBLE], rffi.DOUBLE) def ll_math(x): _error_reset() r = c_func(x) - _check_error(r) + # Error checking fun. Copied from CPython 2.6 + errno = rposix.get_errno() + if isnan(r): + if isnan(x): + errno = 0 + else: + errno = EDOM + elif isinf(r): + if isinf(x) or isnan(x): + errno = 0 + elif can_overflow: + errno = ERANGE + else: + errno = EDOM + if errno: + _likely_raise(errno, r) return r return func_with_new_name(ll_math, 'll_math_' + name) -def new_binary_math_function(name): - 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): - _error_reset() - r = c_func(x, y) - _check_error(r) - return r - - return func_with_new_name(ll_math, 'll_math_' + name) - -# the two above are almost the same, but they're C-c C-v not to go mad -# with meta-programming +unary_math_functions = [ + 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', + 'ceil', 'cos', 'cosh', 'exp', 'fabs', 'floor', + 'log1p', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' + ] +unary_math_functions_can_overflow = [ + 'cosh', 'exp', 'log1p', 'sinh', # why log1p? CPython does it + ] for name in unary_math_functions: - globals()['ll_math_' + name] = new_unary_math_function(name) - -for name in binary_math_functions: - globals()['ll_math_' + name] = new_binary_math_function(name) - + can_overflow = name in unary_math_functions_can_overflow + globals()['ll_math_' + name] = new_unary_math_function(name, can_overflow) From arigo at codespeak.net Tue Mar 16 12:45:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 12:45:38 +0100 (CET) Subject: [pypy-svn] r72274 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module Message-ID: <20100316114538.B599F282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 12:45:37 2010 New Revision: 72274 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Log: Added fmod. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Tue Mar 16 12:45:37 2010 @@ -163,6 +163,25 @@ return math_copysign(x, y) # no error checking needed +def ll_math_fmod(x, y): + if isinf(y): + if isinf(x): + raise ValueError("math domain error") + return x # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN). + + _error_reset() + r = math_fmod(x, y) + errno = rposix.get_errno() + if isnan(r): + if isnan(x) or isnan(y): + errno = 0 + else: + errno = EDOM + if errno: + _likely_raise(errno, r) + return r + + def ll_math_hypot(x, y): # hypot(x, +/-Inf) returns Inf, even if x is a NaN. if isinf(x): @@ -278,9 +297,10 @@ # ____________________________________________________________ unary_math_functions = [ - 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', + 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', 'floor', - 'log1p', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' + 'sin', 'sinh', 'sqrt', 'tan', 'tanh', + # 'log1p', 'acosh', 'asinh', 'atanh', -- added in Python 2.6 ] unary_math_functions_can_overflow = [ 'cosh', 'exp', 'log1p', 'sinh', # why log1p? CPython does it From arigo at codespeak.net Tue Mar 16 12:49:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 12:49:36 +0100 (CET) Subject: [pypy-svn] r72275 - in pypy/branch/ll_math/pypy/rpython: . lltypesystem/module/test Message-ID: <20100316114936.26F86282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 12:49:34 2010 New Revision: 72275 Modified: pypy/branch/ll_math/pypy/rpython/extfuncregistry.py pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Fixes. Modified: pypy/branch/ll_math/pypy/rpython/extfuncregistry.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/extfuncregistry.py (original) +++ pypy/branch/ll_math/pypy/rpython/extfuncregistry.py Tue Mar 16 12:49:34 2010 @@ -29,8 +29,8 @@ ('frexp', [float], (float, int)), ('ldexp', [float, int], float), ('modf', [float], (float, float)), - ] + [(name, [float, float], float) for name in - ll_math.binary_math_functions] + ] + [(name, [float, float], float) + for name in 'atan2', 'fmod', 'hypot', 'pow'] for name, args, res in complex_math_functions: func = getattr(math, name) Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 12:49:34 2010 @@ -30,7 +30,7 @@ locals()[func_name] = next_test del next_test - for name in ll_math.binary_math_functions: + for name in ['atan2', 'fmod', 'hypot', 'pow']: func_name = 'test_%s' % (name,) next_test = new_binary_test(name) next_test.func_name = func_name From arigo at codespeak.net Tue Mar 16 13:32:52 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 13:32:52 +0100 (CET) Subject: [pypy-svn] r72277 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316123252.B9BC0282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 13:32:50 2010 New Revision: 72277 Added: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py - copied unchanged from r72275, pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Start writing real, direct tests for this. Added: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- (empty file) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 13:32:50 2010 @@ -0,0 +1,108 @@ +""" Try to test systematically all cases of ll_math.py. +""" + +from pypy.rpython.lltypesystem.module import ll_math +from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN +import math + +def positiveinf(x): + return isinf(x) and x > 0.0 + +def negativeinf(x): + return isinf(x) and x < 0.0 + +def finite(x): + return not isinf(x) and not isnan(x) + + +class TestMath: + + REGCASES = [ + (name, (0.3,), getattr(math, name)(0.3)) + for name in ll_math.unary_math_functions] + + IRREGCASES = [ + ('atan2', (0.31, 0.123), math.atan2(0.31, 0.123)), + ('fmod', (0.31, 0.123), math.fmod(0.31, 0.123)), + ('hypot', (0.31, 0.123), math.hypot(0.31, 0.123)), + ('pow', (0.31, 0.123), math.pow(0.31, 0.123)), + ('ldexp', (3.375, 2), 13.5), + ('ldexp', (1.0, -10000), 0.0), # underflow + ] + + OVFCASES = [ + ('cosh', (9999.9,), OverflowError), + ('sinh', (9999.9,), OverflowError), + ('exp', (9999.9,), OverflowError), + ('pow', (10.0, 40000.0), OverflowError), + ('ldexp', (10.0, 40000), OverflowError), + ] + + INFCASES = [ + ('acos', (INFINITY,), ValueError), + ('acos', (-INFINITY,), ValueError), + ('asin', (INFINITY,), ValueError), + ('asin', (-INFINITY,), ValueError), + ('atan', (INFINITY,), math.pi / 2), + ('atan', (-INFINITY,), -math.pi / 2), + ('ceil', (INFINITY,), positiveinf), + ('ceil', (-INFINITY,), negativeinf), + ('cos', (INFINITY,), ValueError), + ('cos', (-INFINITY,), ValueError), + ('cosh', (INFINITY,), positiveinf), + ('cosh', (-INFINITY,), positiveinf), + ('exp', (INFINITY,), positiveinf), + ('exp', (-INFINITY,), 0.0), + ('fabs', (INFINITY,), positiveinf), + ('fabs', (-INFINITY,), positiveinf), + ('floor', (INFINITY,), positiveinf), + ('floor', (-INFINITY,), negativeinf), + ('sin', (INFINITY,), ValueError), + ('sin', (-INFINITY,), ValueError), + ('sinh', (INFINITY,), positiveinf), + ('sinh', (-INFINITY,), negativeinf), + ('sqrt', (INFINITY,), positiveinf), + ('sqrt', (-INFINITY,), ValueError), + ('tan', (INFINITY,), ValueError), + ('tan', (-INFINITY,), ValueError), + ('tanh', (INFINITY,), 1.0), + ('tanh', (-INFINITY,), -1.0), + ] + + NANREGCASES = [ + (name, (NAN,), isnan) for name in ll_math.unary_math_functions] + + NANIRREGCASES = [] + + TESTCASES = (REGCASES + IRREGCASES + OVFCASES + + INFCASES + NANREGCASES + NANIRREGCASES) + + +def make_test_case((fnname, args, expected), dict): + # + def test_func(self): + fn = getattr(ll_math, 'll_math_' + fnname) + repr = "%s(%s)" % (fnname, ', '.join(map(str, args))) + try: + got = fn(*args) + except ValueError: + assert expected == ValueError, "%s: got a ValueError" % (repr,) + except OverflowError: + assert expected == OverflowError, "%s: got an OverflowError" % ( + repr,) + else: + if callable(expected): + ok = expected(got) + else: + ok = finite(got) and got == expected + if not ok: + raise AssertionError("%r: got %s" % (repr, got)) + # + dict[fnname] = dict.get(fnname, 0) + 1 + testname = 'test_%s_%d' % (fnname, dict[fnname]) + test_func.func_name = testname + setattr(TestMath, testname, test_func) + +_d = {} +for testcase in TestMath.TESTCASES: + make_test_case(testcase, _d) From arigo at codespeak.net Tue Mar 16 13:51:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 13:51:34 +0100 (CET) Subject: [pypy-svn] r72278 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316125134.74525282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 13:51:32 2010 New Revision: 72278 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Tests tests tests... Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 13:51:32 2010 @@ -28,6 +28,7 @@ ('pow', (0.31, 0.123), math.pow(0.31, 0.123)), ('ldexp', (3.375, 2), 13.5), ('ldexp', (1.0, -10000), 0.0), # underflow + ('frexp', (-1.25,), lambda x: x == (-0.625, 1)), ] OVFCASES = [ @@ -67,15 +68,53 @@ ('tan', (-INFINITY,), ValueError), ('tanh', (INFINITY,), 1.0), ('tanh', (-INFINITY,), -1.0), + ('frexp', (INFINITY,), lambda x: isinf(x[0])), + ('ldexp', (INFINITY, 3), positiveinf), + ('ldexp', (-INFINITY, 3), negativeinf), ] - NANREGCASES = [ - (name, (NAN,), isnan) for name in ll_math.unary_math_functions] + IRREGERRCASES = [ + # + ('atan2', (INFINITY, -2.3), math.pi / 2), + ('atan2', (INFINITY, 0.0), math.pi / 2), + ('atan2', (INFINITY, 3.0), math.pi / 2), + #('atan2', (INFINITY, INFINITY), ?), + ('atan2', (2.1, INFINITY), 0.0), + ('atan2', (0.0, INFINITY), 0.0), + ('atan2', (-0.1, INFINITY), -0.0), + ('atan2', (-INFINITY, 0.4), -math.pi / 2), + ('atan2', (2.1, -INFINITY), math.pi), + ('atan2', (0.0, -INFINITY), math.pi), + ('atan2', (-0.1, -INFINITY), -math.pi), + # + ] + + binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] - NANIRREGCASES = [] + NANCASES1 = [ + (name, (NAN,), isnan) for name in ll_math.unary_math_functions] + NANCASES2 = [ + (name, (NAN, 0.1), isnan) for name in binary_math_functions] + NANCASES3 = [ + (name, (-0.2, NAN), isnan) for name in binary_math_functions] + NANCASES4 = [ + (name, (NAN, -INFINITY), isnan) for name in binary_math_functions + if name != 'hypot'] + NANCASES5 = [ + (name, (INFINITY, NAN), isnan) for name in binary_math_functions + if name != 'hypot'] + NANCASES6 = [ + ('frexp', (NAN,), lambda x: isnan(x[0])), + ('ldexp', (NAN, 2), isnan), + ('hypot', (NAN, INFINITY), positiveinf), + ('hypot', (NAN, -INFINITY), positiveinf), + ('hypot', (INFINITY, NAN), positiveinf), + ('hypot', (-INFINITY, NAN), positiveinf), + ] - TESTCASES = (REGCASES + IRREGCASES + OVFCASES - + INFCASES + NANREGCASES + NANIRREGCASES) + TESTCASES = (REGCASES + IRREGCASES + OVFCASES + INFCASES + IRREGERRCASES + + NANCASES1 + NANCASES2 + NANCASES3 + NANCASES4 + NANCASES5 + + NANCASES6) def make_test_case((fnname, args, expected), dict): @@ -94,7 +133,10 @@ if callable(expected): ok = expected(got) else: - ok = finite(got) and got == expected + gotsign = ll_math.math_copysign(1.0, got) + expectedsign = ll_math.math_copysign(1.0, expected) + ok = finite(got) and (got == expected and + gotsign == expectedsign) if not ok: raise AssertionError("%r: got %s" % (repr, got)) # From arigo at codespeak.net Tue Mar 16 13:56:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 13:56:33 +0100 (CET) Subject: [pypy-svn] r72279 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316125633.A431B282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 13:56:32 2010 New Revision: 72279 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Tests, cont. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 13:56:32 2010 @@ -29,6 +29,8 @@ ('ldexp', (3.375, 2), 13.5), ('ldexp', (1.0, -10000), 0.0), # underflow ('frexp', (-1.25,), lambda x: x == (-0.625, 1)), + ('modf', (4.25,), lambda x: x == (0.25, 4.0)), + ('modf', (-4.25,), lambda x: x == (-0.25, -4.0)), ] OVFCASES = [ @@ -71,6 +73,8 @@ ('frexp', (INFINITY,), lambda x: isinf(x[0])), ('ldexp', (INFINITY, 3), positiveinf), ('ldexp', (-INFINITY, 3), negativeinf), + ('modf', (INFINITY,), lambda x: positiveinf(x[1])), + ('modf', (-INFINITY,), lambda x: negativeinf(x[1])), ] IRREGERRCASES = [ @@ -78,7 +82,7 @@ ('atan2', (INFINITY, -2.3), math.pi / 2), ('atan2', (INFINITY, 0.0), math.pi / 2), ('atan2', (INFINITY, 3.0), math.pi / 2), - #('atan2', (INFINITY, INFINITY), ?), + #('atan2', (INFINITY, INFINITY), ?strange), ('atan2', (2.1, INFINITY), 0.0), ('atan2', (0.0, INFINITY), 0.0), ('atan2', (-0.1, INFINITY), -0.0), @@ -110,6 +114,7 @@ ('hypot', (NAN, -INFINITY), positiveinf), ('hypot', (INFINITY, NAN), positiveinf), ('hypot', (-INFINITY, NAN), positiveinf), + ('modf', (NAN,), lambda x: (isnan(x[0]) and isnan(x[1]))), ] TESTCASES = (REGCASES + IRREGCASES + OVFCASES + INFCASES + IRREGERRCASES From arigo at codespeak.net Tue Mar 16 13:58:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 13:58:05 +0100 (CET) Subject: [pypy-svn] r72280 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316125805.2586E282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 13:58:03 2010 New Revision: 72280 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Tests for fmod. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 13:58:03 2010 @@ -91,6 +91,10 @@ ('atan2', (0.0, -INFINITY), math.pi), ('atan2', (-0.1, -INFINITY), -math.pi), # + ('fmod', (INFINITY, 1.0), ValueError), + ('fmod', (1.0, INFINITY), 1.0), + ('fmod', (1.0, -INFINITY), 1.0), + ('fmod', (INFINITY, INFINITY), ValueError), ] binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] From arigo at codespeak.net Tue Mar 16 13:58:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 13:58:54 +0100 (CET) Subject: [pypy-svn] r72281 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316125854.95C67282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 13:58:53 2010 New Revision: 72281 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Tests for hypot. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 13:58:53 2010 @@ -95,6 +95,9 @@ ('fmod', (1.0, INFINITY), 1.0), ('fmod', (1.0, -INFINITY), 1.0), ('fmod', (INFINITY, INFINITY), ValueError), + # + ('hypot', (-INFINITY, 1.0), positiveinf), + ('hypot', (-2.3, -INFINITY), positiveinf), ] binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] From arigo at codespeak.net Tue Mar 16 14:04:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 14:04:46 +0100 (CET) Subject: [pypy-svn] r72282 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316130446.3B5A4282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 14:04:44 2010 New Revision: 72282 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Tests for pow. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 14:04:44 2010 @@ -26,6 +26,11 @@ ('fmod', (0.31, 0.123), math.fmod(0.31, 0.123)), ('hypot', (0.31, 0.123), math.hypot(0.31, 0.123)), ('pow', (0.31, 0.123), math.pow(0.31, 0.123)), + ('pow', (-0.31, 0.123), ValueError), + ('pow', (-0.5, 2.0), 0.25), + ('pow', (-0.5, 1.0), -0.5), + ('pow', (-0.5, 0.0), 1.0), + ('pow', (-0.5, -1.0), -2.0), ('ldexp', (3.375, 2), 13.5), ('ldexp', (1.0, -10000), 0.0), # underflow ('frexp', (-1.25,), lambda x: x == (-0.625, 1)), @@ -75,6 +80,16 @@ ('ldexp', (-INFINITY, 3), negativeinf), ('modf', (INFINITY,), lambda x: positiveinf(x[1])), ('modf', (-INFINITY,), lambda x: negativeinf(x[1])), + ('pow', (INFINITY, 0.0), 1.0), + ('pow', (INFINITY, 0.001), positiveinf), + ('pow', (INFINITY, -0.001), 0.0), + ('pow', (-INFINITY, 0.0), 1.0), + ('pow', (-INFINITY, 0.001), ValueError), + ('pow', (-INFINITY, -0.001), ValueError), + ('pow', (-INFINITY, 3.0), negativeinf), + ('pow', (-INFINITY, 6.0), positiveinf), + ('pow', (-INFINITY, -13.0), -0.0), + ('pow', (-INFINITY, -128.0), 0.0), ] IRREGERRCASES = [ @@ -145,6 +160,7 @@ if callable(expected): ok = expected(got) else: + assert finite(expected), "badly written test" gotsign = ll_math.math_copysign(1.0, got) expectedsign = ll_math.math_copysign(1.0, expected) ok = finite(got) and (got == expected and From afa at codespeak.net Tue Mar 16 14:11:50 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 16 Mar 2010 14:11:50 +0100 (CET) Subject: [pypy-svn] r72283 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module Message-ID: <20100316131150.F2614282B9E@codespeak.net> Author: afa Date: Tue Mar 16 14:11:49 2010 New Revision: 72283 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Log: Fix for windows: _copysign() needs a leading underscore Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Tue Mar 16 14:11:49 2010 @@ -21,7 +21,11 @@ math_fabs = llexternal('fabs', [rffi.DOUBLE], rffi.DOUBLE) math_log = llexternal('log', [rffi.DOUBLE], rffi.DOUBLE) math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE) -math_copysign = llexternal('copysign', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +if sys.platform[:3] == "win": + _copysign = '_copysign' +else: + _copysign = 'copysign' +math_copysign = llexternal(_copysign, [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE) math_modf = llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE) From arigo at codespeak.net Tue Mar 16 14:11:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 14:11:57 +0100 (CET) Subject: [pypy-svn] r72284 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316131157.24536282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 14:11:55 2010 New Revision: 72284 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Some more corner cases. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 14:11:55 2010 @@ -90,6 +90,18 @@ ('pow', (-INFINITY, 6.0), positiveinf), ('pow', (-INFINITY, -13.0), -0.0), ('pow', (-INFINITY, -128.0), 0.0), + ('pow', (1.001, INFINITY), positiveinf), + ('pow', (1.0, INFINITY), 1.0), + ('pow', (0.999, INFINITY), 0.0), + ('pow', (-0.999,INFINITY), 0.0), + #('pow', (-1.0, INFINITY), 1.0, but strange, could also be -1.0), + ('pow', (-1.001,INFINITY), OverflowError), + ('pow', (1.001, -INFINITY), 0.0), + ('pow', (1.0, -INFINITY), 1.0), + #('pow', (0.999, -INFINITY), positiveinf, but get OverflowError), + #('pow', (INFINITY, INFINITY), positiveinf, but get OverflowError), + ('pow', (INFINITY, -INFINITY), 0.0), + ('pow', (-INFINITY, INFINITY), OverflowError), ] IRREGERRCASES = [ From arigo at codespeak.net Tue Mar 16 14:14:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 14:14:32 +0100 (CET) Subject: [pypy-svn] r72285 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module Message-ID: <20100316131432.38868282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 14:14:30 2010 New Revision: 72285 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Log: Consolidate the two "if windows" checks Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Tue Mar 16 14:14:30 2010 @@ -18,25 +18,24 @@ return rffi.llexternal(name, ARGS, RESULT, compilation_info=eci, sandboxsafe=True) +if sys.platform == 'win32': + underscore = '_' +else: + underscore = '' + math_fabs = llexternal('fabs', [rffi.DOUBLE], rffi.DOUBLE) math_log = llexternal('log', [rffi.DOUBLE], rffi.DOUBLE) math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE) -if sys.platform[:3] == "win": - _copysign = '_copysign' -else: - _copysign = 'copysign' -math_copysign = llexternal(_copysign, [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_copysign = llexternal(underscore + 'copysign', + [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE) math_modf = llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE) math_ldexp = llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE) math_pow = llexternal('pow', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) - -if sys.platform == 'win32': - math_hypot = llexternal('_hypot', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) -else: - math_hypot = llexternal('hypot', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_hypot = llexternal(underscore + 'hypot', + [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) # ____________________________________________________________ # From arigo at codespeak.net Tue Mar 16 14:17:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 14:17:45 +0100 (CET) Subject: [pypy-svn] r72286 - in pypy/branch/ll_math/pypy/rpython/lltypesystem/module: . test Message-ID: <20100316131745.692E2282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 14:17:43 2010 New Revision: 72286 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Add log and log10, tests. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/ll_math.py Tue Mar 16 14:17:43 2010 @@ -302,7 +302,7 @@ unary_math_functions = [ 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', 'floor', - 'sin', 'sinh', 'sqrt', 'tan', 'tanh', + 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'log', 'log10', # 'log1p', 'acosh', 'asinh', 'atanh', -- added in Python 2.6 ] unary_math_functions_can_overflow = [ Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 14:17:43 2010 @@ -44,6 +44,8 @@ ('exp', (9999.9,), OverflowError), ('pow', (10.0, 40000.0), OverflowError), ('ldexp', (10.0, 40000), OverflowError), + ('log', (0.0,), ValueError), + ('log10', (0.0,), ValueError), ] INFCASES = [ @@ -75,6 +77,10 @@ ('tan', (-INFINITY,), ValueError), ('tanh', (INFINITY,), 1.0), ('tanh', (-INFINITY,), -1.0), + ('log', (INFINITY,), positiveinf), + ('log', (-INFINITY,), ValueError), + ('log10', (INFINITY,), positiveinf), + ('log10', (-INFINITY,), ValueError), ('frexp', (INFINITY,), lambda x: isinf(x[0])), ('ldexp', (INFINITY, 3), positiveinf), ('ldexp', (-INFINITY, 3), negativeinf), From arigo at codespeak.net Tue Mar 16 16:25:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:25:42 +0100 (CET) Subject: [pypy-svn] r72288 - pypy/branch/ll_math/pypy/module/math/test Message-ID: <20100316152542.B8F18282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 16:25:39 2010 New Revision: 72288 Added: pypy/branch/ll_math/pypy/module/math/test/ (props changed) pypy/branch/ll_math/pypy/module/math/test/__init__.py (contents, props changed) pypy/branch/ll_math/pypy/module/math/test/test_direct.py (contents, props changed) - copied, changed from r72286, pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: A test that runs directly on top of the host Python. Added: pypy/branch/ll_math/pypy/module/math/test/__init__.py ============================================================================== Copied: pypy/branch/ll_math/pypy/module/math/test/test_direct.py (from r72286, pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py) ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/module/math/test/test_direct.py Tue Mar 16 16:25:39 2010 @@ -1,9 +1,8 @@ -""" Try to test systematically all cases of ll_math.py. +""" Try to test systematically all cases of the math module. """ -from pypy.rpython.lltypesystem.module import ll_math +import py, sys, math from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN -import math def positiveinf(x): return isinf(x) and x > 0.0 @@ -15,11 +14,17 @@ return not isinf(x) and not isnan(x) -class TestMath: +unary_math_functions = ['acos', 'asin', 'atan', + 'ceil', 'cos', 'cosh', 'exp', 'fabs', 'floor', + 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'log', 'log10'] +binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] + + +class MathTests: REGCASES = [ (name, (0.3,), getattr(math, name)(0.3)) - for name in ll_math.unary_math_functions] + for name in unary_math_functions] IRREGCASES = [ ('atan2', (0.31, 0.123), math.atan2(0.31, 0.123)), @@ -136,7 +141,7 @@ binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] NANCASES1 = [ - (name, (NAN,), isnan) for name in ll_math.unary_math_functions] + (name, (NAN,), isnan) for name in unary_math_functions] NANCASES2 = [ (name, (NAN, 0.1), isnan) for name in binary_math_functions] NANCASES3 = [ @@ -162,10 +167,16 @@ + NANCASES6) +class TestDirect(MathTests): + pass + def make_test_case((fnname, args, expected), dict): # def test_func(self): - fn = getattr(ll_math, 'll_math_' + fnname) + if '__pypy__' not in sys.builtin_module_names: + if sys.version_info < (2, 6): + py.test.skip("inconsistent behavior before 2.6") + fn = getattr(math, fnname) repr = "%s(%s)" % (fnname, ', '.join(map(str, args))) try: got = fn(*args) @@ -179,8 +190,9 @@ ok = expected(got) else: assert finite(expected), "badly written test" - gotsign = ll_math.math_copysign(1.0, got) - expectedsign = ll_math.math_copysign(1.0, expected) + gotsign = expectedsign = 1 + if got < 0.0: gotsign = -gotsign + if expected < 0.0: expectedsign = -expectedsign ok = finite(got) and (got == expected and gotsign == expectedsign) if not ok: @@ -189,8 +201,8 @@ dict[fnname] = dict.get(fnname, 0) + 1 testname = 'test_%s_%d' % (fnname, dict[fnname]) test_func.func_name = testname - setattr(TestMath, testname, test_func) + setattr(TestDirect, testname, test_func) _d = {} -for testcase in TestMath.TESTCASES: +for testcase in TestDirect.TESTCASES: make_test_case(testcase, _d) From arigo at codespeak.net Tue Mar 16 16:44:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:44:11 +0100 (CET) Subject: [pypy-svn] r72289 - pypy/branch/ll_math/pypy/module/math/test Message-ID: <20100316154411.79767282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 16:44:09 2010 New Revision: 72289 Added: pypy/branch/ll_math/pypy/module/math/test/test_math.py (contents, props changed) Modified: pypy/branch/ll_math/pypy/module/math/test/test_direct.py Log: Add test_math, which tests the mixed module (or directly the underlying host interpreter when run with -A). Modified: pypy/branch/ll_math/pypy/module/math/test/test_direct.py ============================================================================== --- pypy/branch/ll_math/pypy/module/math/test/test_direct.py (original) +++ pypy/branch/ll_math/pypy/module/math/test/test_direct.py Tue Mar 16 16:44:09 2010 @@ -4,6 +4,11 @@ import py, sys, math from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN +consistent = True +if '__pypy__' not in sys.builtin_module_names: + if sys.version_info < (2, 6): + consistent = False + def positiveinf(x): return isinf(x) and x > 0.0 @@ -170,33 +175,35 @@ class TestDirect(MathTests): pass +def do_test(fn, fnname, args, expected): + repr = "%s(%s)" % (fnname, ', '.join(map(str, args))) + try: + got = fn(*args) + except ValueError: + assert expected == ValueError, "%s: got a ValueError" % (repr,) + except OverflowError: + assert expected == OverflowError, "%s: got an OverflowError" % ( + repr,) + else: + if callable(expected): + ok = expected(got) + else: + assert finite(expected), "badly written test" + gotsign = expectedsign = 1 + if got < 0.0: gotsign = -gotsign + if expected < 0.0: expectedsign = -expectedsign + ok = finite(got) and (got == expected and + gotsign == expectedsign) + if not ok: + raise AssertionError("%r: got %s" % (repr, got)) + def make_test_case((fnname, args, expected), dict): # def test_func(self): - if '__pypy__' not in sys.builtin_module_names: - if sys.version_info < (2, 6): - py.test.skip("inconsistent behavior before 2.6") + if not consistent: + py.test.skip("inconsistent behavior before 2.6") fn = getattr(math, fnname) - repr = "%s(%s)" % (fnname, ', '.join(map(str, args))) - try: - got = fn(*args) - except ValueError: - assert expected == ValueError, "%s: got a ValueError" % (repr,) - except OverflowError: - assert expected == OverflowError, "%s: got an OverflowError" % ( - repr,) - else: - if callable(expected): - ok = expected(got) - else: - assert finite(expected), "badly written test" - gotsign = expectedsign = 1 - if got < 0.0: gotsign = -gotsign - if expected < 0.0: expectedsign = -expectedsign - ok = finite(got) and (got == expected and - gotsign == expectedsign) - if not ok: - raise AssertionError("%r: got %s" % (repr, got)) + do_test(fn, fnname, args, expected) # dict[fnname] = dict.get(fnname, 0) + 1 testname = 'test_%s_%d' % (fnname, dict[fnname]) Added: pypy/branch/ll_math/pypy/module/math/test/test_math.py ============================================================================== --- (empty file) +++ pypy/branch/ll_math/pypy/module/math/test/test_math.py Tue Mar 16 16:44:09 2010 @@ -0,0 +1,37 @@ +import sys +from pypy.conftest import gettestobjspace +from pypy.module.math.test import test_direct + + +class AppTestMath: + def setup_class(cls): + cls.space = gettestobjspace(usemodules=['math']) + cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) + cls.w_consistent = cls.space.wrap(test_direct.consistent) + + def test_all_cases(self): + import math + for fnname, args, expected in self.cases: + fn = getattr(math, fnname) + print fn, args + try: + got = fn(*args) + except ValueError: + assert expected == ValueError + except OverflowError: + if not self.consistent: + if expected == ValueError: + continue # e.g. for 'log' + if callable(expected): + continue # e.g. for 'ceil' + assert expected == OverflowError + else: + if callable(expected): + ok = expected(got) + else: + gotsign = expectedsign = 1 + if got < 0.0: gotsign = -gotsign + if expected < 0.0: expectedsign = -expectedsign + ok = got == expected and gotsign == expectedsign + if not ok: + raise AssertionError("%r: got %s" % (repr, got)) From arigo at codespeak.net Tue Mar 16 16:46:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:46:31 +0100 (CET) Subject: [pypy-svn] r72290 - pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test Message-ID: <20100316154631.1B4E1282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 16:46:29 2010 New Revision: 72290 Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Log: Share the tests with pypy/module/math/test. Modified: pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py Tue Mar 16 16:46:29 2010 @@ -2,165 +2,11 @@ """ from pypy.rpython.lltypesystem.module import ll_math -from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN -import math +from pypy.module.math.test.test_direct import MathTests, finite -def positiveinf(x): - return isinf(x) and x > 0.0 - -def negativeinf(x): - return isinf(x) and x < 0.0 - -def finite(x): - return not isinf(x) and not isnan(x) - - -class TestMath: - - REGCASES = [ - (name, (0.3,), getattr(math, name)(0.3)) - for name in ll_math.unary_math_functions] - - IRREGCASES = [ - ('atan2', (0.31, 0.123), math.atan2(0.31, 0.123)), - ('fmod', (0.31, 0.123), math.fmod(0.31, 0.123)), - ('hypot', (0.31, 0.123), math.hypot(0.31, 0.123)), - ('pow', (0.31, 0.123), math.pow(0.31, 0.123)), - ('pow', (-0.31, 0.123), ValueError), - ('pow', (-0.5, 2.0), 0.25), - ('pow', (-0.5, 1.0), -0.5), - ('pow', (-0.5, 0.0), 1.0), - ('pow', (-0.5, -1.0), -2.0), - ('ldexp', (3.375, 2), 13.5), - ('ldexp', (1.0, -10000), 0.0), # underflow - ('frexp', (-1.25,), lambda x: x == (-0.625, 1)), - ('modf', (4.25,), lambda x: x == (0.25, 4.0)), - ('modf', (-4.25,), lambda x: x == (-0.25, -4.0)), - ] - - OVFCASES = [ - ('cosh', (9999.9,), OverflowError), - ('sinh', (9999.9,), OverflowError), - ('exp', (9999.9,), OverflowError), - ('pow', (10.0, 40000.0), OverflowError), - ('ldexp', (10.0, 40000), OverflowError), - ('log', (0.0,), ValueError), - ('log10', (0.0,), ValueError), - ] - - INFCASES = [ - ('acos', (INFINITY,), ValueError), - ('acos', (-INFINITY,), ValueError), - ('asin', (INFINITY,), ValueError), - ('asin', (-INFINITY,), ValueError), - ('atan', (INFINITY,), math.pi / 2), - ('atan', (-INFINITY,), -math.pi / 2), - ('ceil', (INFINITY,), positiveinf), - ('ceil', (-INFINITY,), negativeinf), - ('cos', (INFINITY,), ValueError), - ('cos', (-INFINITY,), ValueError), - ('cosh', (INFINITY,), positiveinf), - ('cosh', (-INFINITY,), positiveinf), - ('exp', (INFINITY,), positiveinf), - ('exp', (-INFINITY,), 0.0), - ('fabs', (INFINITY,), positiveinf), - ('fabs', (-INFINITY,), positiveinf), - ('floor', (INFINITY,), positiveinf), - ('floor', (-INFINITY,), negativeinf), - ('sin', (INFINITY,), ValueError), - ('sin', (-INFINITY,), ValueError), - ('sinh', (INFINITY,), positiveinf), - ('sinh', (-INFINITY,), negativeinf), - ('sqrt', (INFINITY,), positiveinf), - ('sqrt', (-INFINITY,), ValueError), - ('tan', (INFINITY,), ValueError), - ('tan', (-INFINITY,), ValueError), - ('tanh', (INFINITY,), 1.0), - ('tanh', (-INFINITY,), -1.0), - ('log', (INFINITY,), positiveinf), - ('log', (-INFINITY,), ValueError), - ('log10', (INFINITY,), positiveinf), - ('log10', (-INFINITY,), ValueError), - ('frexp', (INFINITY,), lambda x: isinf(x[0])), - ('ldexp', (INFINITY, 3), positiveinf), - ('ldexp', (-INFINITY, 3), negativeinf), - ('modf', (INFINITY,), lambda x: positiveinf(x[1])), - ('modf', (-INFINITY,), lambda x: negativeinf(x[1])), - ('pow', (INFINITY, 0.0), 1.0), - ('pow', (INFINITY, 0.001), positiveinf), - ('pow', (INFINITY, -0.001), 0.0), - ('pow', (-INFINITY, 0.0), 1.0), - ('pow', (-INFINITY, 0.001), ValueError), - ('pow', (-INFINITY, -0.001), ValueError), - ('pow', (-INFINITY, 3.0), negativeinf), - ('pow', (-INFINITY, 6.0), positiveinf), - ('pow', (-INFINITY, -13.0), -0.0), - ('pow', (-INFINITY, -128.0), 0.0), - ('pow', (1.001, INFINITY), positiveinf), - ('pow', (1.0, INFINITY), 1.0), - ('pow', (0.999, INFINITY), 0.0), - ('pow', (-0.999,INFINITY), 0.0), - #('pow', (-1.0, INFINITY), 1.0, but strange, could also be -1.0), - ('pow', (-1.001,INFINITY), OverflowError), - ('pow', (1.001, -INFINITY), 0.0), - ('pow', (1.0, -INFINITY), 1.0), - #('pow', (0.999, -INFINITY), positiveinf, but get OverflowError), - #('pow', (INFINITY, INFINITY), positiveinf, but get OverflowError), - ('pow', (INFINITY, -INFINITY), 0.0), - ('pow', (-INFINITY, INFINITY), OverflowError), - ] - - IRREGERRCASES = [ - # - ('atan2', (INFINITY, -2.3), math.pi / 2), - ('atan2', (INFINITY, 0.0), math.pi / 2), - ('atan2', (INFINITY, 3.0), math.pi / 2), - #('atan2', (INFINITY, INFINITY), ?strange), - ('atan2', (2.1, INFINITY), 0.0), - ('atan2', (0.0, INFINITY), 0.0), - ('atan2', (-0.1, INFINITY), -0.0), - ('atan2', (-INFINITY, 0.4), -math.pi / 2), - ('atan2', (2.1, -INFINITY), math.pi), - ('atan2', (0.0, -INFINITY), math.pi), - ('atan2', (-0.1, -INFINITY), -math.pi), - # - ('fmod', (INFINITY, 1.0), ValueError), - ('fmod', (1.0, INFINITY), 1.0), - ('fmod', (1.0, -INFINITY), 1.0), - ('fmod', (INFINITY, INFINITY), ValueError), - # - ('hypot', (-INFINITY, 1.0), positiveinf), - ('hypot', (-2.3, -INFINITY), positiveinf), - ] - - binary_math_functions = ['atan2', 'fmod', 'hypot', 'pow'] - - NANCASES1 = [ - (name, (NAN,), isnan) for name in ll_math.unary_math_functions] - NANCASES2 = [ - (name, (NAN, 0.1), isnan) for name in binary_math_functions] - NANCASES3 = [ - (name, (-0.2, NAN), isnan) for name in binary_math_functions] - NANCASES4 = [ - (name, (NAN, -INFINITY), isnan) for name in binary_math_functions - if name != 'hypot'] - NANCASES5 = [ - (name, (INFINITY, NAN), isnan) for name in binary_math_functions - if name != 'hypot'] - NANCASES6 = [ - ('frexp', (NAN,), lambda x: isnan(x[0])), - ('ldexp', (NAN, 2), isnan), - ('hypot', (NAN, INFINITY), positiveinf), - ('hypot', (NAN, -INFINITY), positiveinf), - ('hypot', (INFINITY, NAN), positiveinf), - ('hypot', (-INFINITY, NAN), positiveinf), - ('modf', (NAN,), lambda x: (isnan(x[0]) and isnan(x[1]))), - ] - - TESTCASES = (REGCASES + IRREGCASES + OVFCASES + INFCASES + IRREGERRCASES - + NANCASES1 + NANCASES2 + NANCASES3 + NANCASES4 + NANCASES5 - + NANCASES6) +class TestMath(MathTests): + pass def make_test_case((fnname, args, expected), dict): # From arigo at codespeak.net Tue Mar 16 16:47:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:47:02 +0100 (CET) Subject: [pypy-svn] r72291 - pypy/branch/ll_math/pypy/module/math Message-ID: <20100316154702.6E639282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 16:47:00 2010 New Revision: 72291 Removed: pypy/branch/ll_math/pypy/module/math/readme.test Log: Remove this note. From arigo at codespeak.net Tue Mar 16 16:50:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:50:44 +0100 (CET) Subject: [pypy-svn] r72292 - in pypy/trunk/pypy: module/math module/math/test rpython rpython/lltypesystem/module rpython/lltypesystem/module/test Message-ID: <20100316155044.44442282B9E@codespeak.net> Author: arigo Date: Tue Mar 16 16:50:42 2010 New Revision: 72292 Added: pypy/trunk/pypy/module/math/test/ (props changed) - copied from r72291, pypy/branch/ll_math/pypy/module/math/test/ pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py - copied unchanged from r72291, pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_ll_math.py pypy/trunk/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py - copied unchanged from r72291, pypy/branch/ll_math/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py Removed: pypy/trunk/pypy/module/math/readme.test Modified: pypy/trunk/pypy/rpython/extfuncregistry.py pypy/trunk/pypy/rpython/lltypesystem/module/ll_math.py Log: Improve error testing in the math module, following CPython 2.6. This should be safe against the underlying C-level functions like sqrt() setting errno or not. Also improves testing of this. (merged from branch/ll_math) Modified: pypy/trunk/pypy/rpython/extfuncregistry.py ============================================================================== --- pypy/trunk/pypy/rpython/extfuncregistry.py (original) +++ pypy/trunk/pypy/rpython/extfuncregistry.py Tue Mar 16 16:50:42 2010 @@ -29,8 +29,8 @@ ('frexp', [float], (float, int)), ('ldexp', [float, int], float), ('modf', [float], (float, float)), - ] + [(name, [float, float], float) for name in - ll_math.binary_math_functions] + ] + [(name, [float, float], float) + for name in 'atan2', 'fmod', 'hypot', 'pow'] for name, args, res in complex_math_functions: func = getattr(math, name) 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 Tue Mar 16 16:50:42 2010 @@ -7,108 +7,308 @@ from pypy.tool.sourcetools import func_with_new_name from pypy.rlib import rposix from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.rlib.rarithmetic import isinf +from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN -math_frexp = rffi.llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE, - sandboxsafe=True) -math_modf = rffi.llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE, - sandboxsafe=True) -math_ldexp = rffi.llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE, - sandboxsafe=True) +if sys.platform[:3] == "win": + eci = ExternalCompilationInfo(libraries=[]) +else: + eci = ExternalCompilationInfo(libraries=['m']) -unary_math_functions = [ - 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' - ] +def llexternal(name, ARGS, RESULT): + return rffi.llexternal(name, ARGS, RESULT, compilation_info=eci, + sandboxsafe=True) + +if sys.platform == 'win32': + underscore = '_' +else: + underscore = '' + +math_fabs = llexternal('fabs', [rffi.DOUBLE], rffi.DOUBLE) +math_log = llexternal('log', [rffi.DOUBLE], rffi.DOUBLE) +math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE) +math_copysign = llexternal(underscore + 'copysign', + [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_atan2 = llexternal('atan2', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_frexp = llexternal('frexp', [rffi.DOUBLE, rffi.INTP], rffi.DOUBLE) +math_modf = llexternal('modf', [rffi.DOUBLE, rffi.DOUBLEP], rffi.DOUBLE) +math_ldexp = llexternal('ldexp', [rffi.DOUBLE, rffi.INT], rffi.DOUBLE) +math_pow = llexternal('pow', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) +math_hypot = llexternal(underscore + 'hypot', + [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) + +# ____________________________________________________________ +# +# Error handling functions + +ERANGE = errno.ERANGE +EDOM = errno.EDOM + +def _error_reset(): + rposix.set_errno(0) + +def _likely_raise(errno, x): + """Call this with errno != 0. It usually raises the proper RPython + exception, but may also just ignore it and return in case of underflow. + """ + assert errno + if errno == ERANGE: + # We consider underflow to not be an error, like CPython. + # On some platforms (Ubuntu/ia64) it seems that errno can be + # set to ERANGE for subnormal results that do *not* underflow + # to zero. So to be safe, we'll ignore ERANGE whenever the + # function result is less than one in absolute value. + if math_fabs(x) < 1.0: + return + raise OverflowError("math range error") + else: + raise ValueError("math domain error") + +# ____________________________________________________________ +# +# Custom implementations + + +def ll_math_atan2(y, x): + """wrapper for atan2 that deals directly with special cases before + delegating to the platform libm for the remaining cases. This + is necessary to get consistent behaviour across platforms. + Windows, FreeBSD and alpha Tru64 are amongst platforms that don't + always follow C99. + """ + if isnan(x) or isnan(y): + return NAN + + if isinf(y): + if isinf(x): + if math_copysign(1.0, x) == 1.0: + # atan2(+-inf, +inf) == +-pi/4 + return math_copysign(0.25 * math.pi, y) + else: + # atan2(+-inf, -inf) == +-pi*3/4 + return math_copysign(0.75 * math.pi, y) + # atan2(+-inf, x) == +-pi/2 for finite x + return math_copysign(0.5 * math.pi, y) + + if isinf(x) or y == 0.0: + if math_copysign(1.0, x) == 1.0: + # atan2(+-y, +inf) = atan2(+-0, +x) = +-0. + return math_copysign(0.0, y) + else: + # atan2(+-y, -inf) = atan2(+-0., -x) = +-pi. + return math_copysign(math.pi, y) + + return math_atan2(y, x) + + +# XXX Various platforms (Solaris, OpenBSD) do nonstandard things for log(0), +# log(-ve), log(NaN). For now I'm ignoring this issue as these are a bit +# more marginal platforms for us. -binary_math_functions = [ - 'atan2', 'fmod', 'hypot', 'pow' - ] def ll_math_frexp(x): - exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') - try: - _error_reset() - mantissa = math_frexp(x, exp_p) - _check_error(mantissa) - exponent = rffi.cast(lltype.Signed, exp_p[0]) - finally: - lltype.free(exp_p, flavor='raw') + # deal with special cases directly, to sidestep platform differences + if isnan(x) or isinf(x) or not x: + mantissa = x + exponent = 0 + else: + exp_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') + try: + mantissa = math_frexp(x, exp_p) + exponent = rffi.cast(lltype.Signed, exp_p[0]) + finally: + lltype.free(exp_p, flavor='raw') return (mantissa, exponent) + +INT_MAX = int(2**31-1) +INT_MIN = int(-2**31) + +def ll_math_ldexp(x, exp): + if x == 0.0 or isinf(x) or isnan(x): + return x # NaNs, zeros and infinities are returned unchanged + if exp > INT_MAX: + # overflow (64-bit platforms only) + r = math_copysign(INFINITY, x) + errno = ERANGE + elif exp < INT_MIN: + # underflow to +-0 (64-bit platforms only) + r = math_copysign(0.0, x) + errno = 0 + else: + _error_reset() + r = math_ldexp(x, exp) + errno = rposix.get_errno() + if isinf(r): + errno = ERANGE + if errno: + _likely_raise(errno, r) + return r + + def ll_math_modf(x): + # some platforms don't do the right thing for NaNs and + # infinities, so we take care of special cases directly. + if isinf(x): + return (math_copysign(0.0, x), x) + elif isnan(x): + return (x, x) intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw') try: - _error_reset() fracpart = math_modf(x, intpart_p) - _check_error(fracpart) intpart = intpart_p[0] finally: lltype.free(intpart_p, flavor='raw') return (fracpart, intpart) -def ll_math_ldexp(x, exp): + +def ll_math_copysign(x, y): + return math_copysign(x, y) # no error checking needed + + +def ll_math_fmod(x, y): + if isinf(y): + if isinf(x): + raise ValueError("math domain error") + return x # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN). + _error_reset() - r = math_ldexp(x, exp) - _check_error(r) + r = math_fmod(x, y) + errno = rposix.get_errno() + if isnan(r): + if isnan(x) or isnan(y): + errno = 0 + else: + errno = EDOM + if errno: + _likely_raise(errno, r) return r -def _error_reset(): - rposix.set_errno(0) -ERANGE = errno.ERANGE -def _check_error(x): - errno = rposix.get_errno() +def ll_math_hypot(x, y): + # hypot(x, +/-Inf) returns Inf, even if x is a NaN. if isinf(x): - errno = ERANGE + return math_fabs(x) + if isinf(y): + return math_fabs(y) + + _error_reset() + r = math_hypot(x, y) + errno = rposix.get_errno() + if isnan(r): + if isnan(x) or isnan(y): + errno = 0 + else: + errno = EDOM + elif isinf(r): + if isinf(x) or isnan(x) or isinf(y) or isnan(y): + errno = 0 + else: + errno = ERANGE if errno: - if errno == ERANGE: - if not x: - return # we consider underflow to not be an error, like CPython - raise OverflowError("math range error") + _likely_raise(errno, r) + return r + + +def ll_math_pow(x, y): + # deal directly with IEEE specials, to cope with problems on various + # platforms whose semantics don't exactly match C99 + + if isnan(x): + if y == 0.0: + return 1.0 # NaN**0 = 1 + return x + + elif isnan(y): + if x == 1.0: + return 1.0 # 1**Nan = 1 + return y + + elif isinf(x): + odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0 + if y > 0.0: + if odd_y: + return x + return math_fabs(x) + elif y == 0.0: + return 1.0 + else: # y < 0.0 + if odd_y: + return math_copysign(0.0, x) + return 0.0 + + elif isinf(y): + if math_fabs(x) == 1.0: + return 1.0 + elif y > 0.0 and math_fabs(x) > 1.0: + return y + elif y < 0.0 and math_fabs(x) < 1.0: + if x == 0.0: + raise ValueError("0**-inf: divide by zero") + return -y # result is +inf else: - raise ValueError("math domain error") + return 0.0 -if sys.platform[:3] == "win": - eci = ExternalCompilationInfo(libraries=[]) -else: - eci = ExternalCompilationInfo(libraries=['m']) + _error_reset() + r = math_pow(x, y) + errno = rposix.get_errno() + if isnan(r): + # a NaN result should arise only from (-ve)**(finite non-integer) + errno = EDOM + elif isinf(r): + # an infinite result here arises either from: + # (A) (+/-0.)**negative (-> divide-by-zero) + # (B) overflow of x**y with x and y finite + if x == 0.0: + errno = EDOM + else: + errno = ERANGE + if errno: + _likely_raise(errno, r) + return r +# ____________________________________________________________ +# +# Default implementations -def new_unary_math_function(name): - c_func = rffi.llexternal(name, [rffi.DOUBLE], rffi.DOUBLE, - compilation_info=eci, sandboxsafe=True) +def new_unary_math_function(name, can_overflow): + c_func = llexternal(name, [rffi.DOUBLE], rffi.DOUBLE) def ll_math(x): _error_reset() r = c_func(x) - _check_error(r) + # Error checking fun. Copied from CPython 2.6 + errno = rposix.get_errno() + if isnan(r): + if isnan(x): + errno = 0 + else: + errno = EDOM + elif isinf(r): + if isinf(x) or isnan(x): + errno = 0 + elif can_overflow: + errno = ERANGE + else: + errno = EDOM + if errno: + _likely_raise(errno, r) return r return func_with_new_name(ll_math, 'll_math_' + name) -def new_binary_math_function(name): - 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): - _error_reset() - r = c_func(x, y) - _check_error(r) - return r - - return func_with_new_name(ll_math, 'll_math_' + name) - -# the two above are almost the same, but they're C-c C-v not to go mad -# with meta-programming +unary_math_functions = [ + 'acos', 'asin', 'atan', + 'ceil', 'cos', 'cosh', 'exp', 'fabs', 'floor', + 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'log', 'log10', + # 'log1p', 'acosh', 'asinh', 'atanh', -- added in Python 2.6 + ] +unary_math_functions_can_overflow = [ + 'cosh', 'exp', 'log1p', 'sinh', # why log1p? CPython does it + ] for name in unary_math_functions: - globals()['ll_math_' + name] = new_unary_math_function(name) - -for name in binary_math_functions: - globals()['ll_math_' + name] = new_binary_math_function(name) - + can_overflow = name in unary_math_functions_can_overflow + globals()['ll_math_' + name] = new_unary_math_function(name, can_overflow) From arigo at codespeak.net Tue Mar 16 16:50:56 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Mar 2010 16:50:56 +0100 (CET) Subject: [pypy-svn] r72293 - pypy/branch/ll_math Message-ID: <20100316155056.D376C282BD8@codespeak.net> Author: arigo Date: Tue Mar 16 16:50:55 2010 New Revision: 72293 Removed: pypy/branch/ll_math/ Log: Branch merged. From arigo at codespeak.net Wed Mar 17 12:19:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 12:19:51 +0100 (CET) Subject: [pypy-svn] r72301 - in pypy/trunk/pypy: module/math/test rpython/lltypesystem/module/test translator/c/test Message-ID: <20100317111951.F1AF0282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 12:19:47 2010 New Revision: 72301 Added: pypy/trunk/pypy/translator/c/test/test_math.py (contents, props changed) Modified: pypy/trunk/pypy/module/math/test/test_direct.py pypy/trunk/pypy/module/math/test/test_math.py pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py pypy/trunk/pypy/translator/c/test/test_extfunc.py Log: Improve tests. Fix an "oups": OverflowError is callable too. Add C tests too. Modified: pypy/trunk/pypy/module/math/test/test_direct.py ============================================================================== --- pypy/trunk/pypy/module/math/test/test_direct.py (original) +++ pypy/trunk/pypy/module/math/test/test_direct.py Wed Mar 17 12:19:47 2010 @@ -4,10 +4,10 @@ import py, sys, math from pypy.rlib.rarithmetic import isinf, isnan, INFINITY, NAN -consistent = True +consistent_host = True if '__pypy__' not in sys.builtin_module_names: if sys.version_info < (2, 6): - consistent = False + consistent_host = False def positiveinf(x): return isinf(x) and x > 0.0 @@ -100,8 +100,8 @@ ('pow', (INFINITY, 0.001), positiveinf), ('pow', (INFINITY, -0.001), 0.0), ('pow', (-INFINITY, 0.0), 1.0), - ('pow', (-INFINITY, 0.001), ValueError), - ('pow', (-INFINITY, -0.001), ValueError), + ('pow', (-INFINITY, 0.001), positiveinf), + ('pow', (-INFINITY, -0.001), 0.0), ('pow', (-INFINITY, 3.0), negativeinf), ('pow', (-INFINITY, 6.0), positiveinf), ('pow', (-INFINITY, -13.0), -0.0), @@ -111,13 +111,13 @@ ('pow', (0.999, INFINITY), 0.0), ('pow', (-0.999,INFINITY), 0.0), #('pow', (-1.0, INFINITY), 1.0, but strange, could also be -1.0), - ('pow', (-1.001,INFINITY), OverflowError), + ('pow', (-1.001,INFINITY), positiveinf), ('pow', (1.001, -INFINITY), 0.0), ('pow', (1.0, -INFINITY), 1.0), #('pow', (0.999, -INFINITY), positiveinf, but get OverflowError), #('pow', (INFINITY, INFINITY), positiveinf, but get OverflowError), ('pow', (INFINITY, -INFINITY), 0.0), - ('pow', (-INFINITY, INFINITY), OverflowError), + ('pow', (-INFINITY, INFINITY), positiveinf), ] IRREGERRCASES = [ @@ -167,6 +167,8 @@ ('modf', (NAN,), lambda x: (isnan(x[0]) and isnan(x[1]))), ] + # The list of test cases. Note that various tests import this, + # notably in rpython/lltypesystem/module and in translator/c/test. TESTCASES = (REGCASES + IRREGCASES + OVFCASES + INFCASES + IRREGERRCASES + NANCASES1 + NANCASES2 + NANCASES3 + NANCASES4 + NANCASES5 + NANCASES6) @@ -175,6 +177,25 @@ class TestDirect(MathTests): pass +def get_tester(expected): + if type(expected) is type(Exception): + def tester(value): + return False + elif callable(expected): + def tester(value): + ok = expected(value) + assert isinstance(ok, bool) + return ok + else: + assert finite(expected), "badly written test" + def tester(got): + gotsign = expectedsign = 1 + if got < 0.0: gotsign = -gotsign + if expected < 0.0: expectedsign = -expectedsign + return finite(got) and (got == expected and + gotsign == expectedsign) + return tester + def do_test(fn, fnname, args, expected): repr = "%s(%s)" % (fnname, ', '.join(map(str, args))) try: @@ -185,22 +206,13 @@ assert expected == OverflowError, "%s: got an OverflowError" % ( repr,) else: - if callable(expected): - ok = expected(got) - else: - assert finite(expected), "badly written test" - gotsign = expectedsign = 1 - if got < 0.0: gotsign = -gotsign - if expected < 0.0: expectedsign = -expectedsign - ok = finite(got) and (got == expected and - gotsign == expectedsign) - if not ok: + if not get_tester(expected)(got): raise AssertionError("%r: got %s" % (repr, got)) def make_test_case((fnname, args, expected), dict): # def test_func(self): - if not consistent: + if not consistent_host: py.test.skip("inconsistent behavior before 2.6") fn = getattr(math, fnname) do_test(fn, fnname, args, expected) Modified: pypy/trunk/pypy/module/math/test/test_math.py ============================================================================== --- pypy/trunk/pypy/module/math/test/test_math.py (original) +++ pypy/trunk/pypy/module/math/test/test_math.py Wed Mar 17 12:19:47 2010 @@ -7,9 +7,11 @@ def setup_class(cls): cls.space = gettestobjspace(usemodules=['math']) cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES) - cls.w_consistent = cls.space.wrap(test_direct.consistent) + cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host) def test_all_cases(self): + if not self.consistent_host: + skip("please test this on top of PyPy or CPython >= 2.6") import math for fnname, args, expected in self.cases: fn = getattr(math, fnname) @@ -19,14 +21,11 @@ except ValueError: assert expected == ValueError except OverflowError: - if not self.consistent: - if expected == ValueError: - continue # e.g. for 'log' - if callable(expected): - continue # e.g. for 'ceil' assert expected == OverflowError else: - if callable(expected): + if type(expected) is type(Exception): + ok = False + elif callable(expected): ok = expected(got) else: gotsign = expectedsign = 1 @@ -34,4 +33,5 @@ if expected < 0.0: expectedsign = -expectedsign ok = got == expected and gotsign == expectedsign if not ok: - raise AssertionError("%r: got %s" % (repr, got)) + raise AssertionError("%s(%s): got %s" % ( + fnname, ', '.join(map(str, args)), got)) Modified: pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py Wed Mar 17 12:19:47 2010 @@ -2,7 +2,7 @@ """ from pypy.rpython.lltypesystem.module import ll_math -from pypy.module.math.test.test_direct import MathTests, finite +from pypy.module.math.test.test_direct import MathTests, get_tester class TestMath(MathTests): @@ -21,15 +21,7 @@ assert expected == OverflowError, "%s: got an OverflowError" % ( repr,) else: - if callable(expected): - ok = expected(got) - else: - assert finite(expected), "badly written test" - gotsign = ll_math.math_copysign(1.0, got) - expectedsign = ll_math.math_copysign(1.0, expected) - ok = finite(got) and (got == expected and - gotsign == expectedsign) - if not ok: + if not get_tester(expected)(got): raise AssertionError("%r: got %s" % (repr, got)) # dict[fnname] = dict.get(fnname, 0) + 1 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 Wed Mar 17 12:19:47 2010 @@ -235,93 +235,6 @@ res = f1("echo hello") assert res == 0 -def test_math_pow(): - import math - def fn(x, y): - return math.pow(x, y) - f = compile(fn, [float, float]) - assert f(2.0, 3.0) == math.pow(2.0, 3.0) - assert f(3.0, 2.0) == math.pow(3.0, 2.0) - assert f(2.3, 0.0) == math.pow(2.3, 0.0) - assert f(2.3, -1.0) == math.pow(2.3, -1.0) - assert f(2.3, -2.0) == math.pow(2.3, -2.0) - assert f(2.3, 0.5) == math.pow(2.3, 0.5) - assert f(4.0, 0.5) == math.pow(4.0, 0.5) - -def test_math_frexp(): - from math import frexp - def fn(x): - return frexp(x) - f = compile(fn, [float]) - assert f(10.123) == frexp(10.123) - -def test_math_modf(): - from math import modf - def fn(x): - return modf(x) - f = compile(fn, [float]) - assert f(10.123) == modf(10.123) - -def test_math_hypot(): - from math import hypot - def fn(x, y): - return hypot(x, y) - f = compile(fn, [float, float]) - assert f(9812.231, 1234) == hypot(9812.231, 1234) - -simple_math_functions = [ - 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', - 'floor', 'log', 'log10', 'sin', 'sinh', 'sqrt', 'tan', 'tanh' - ] - -def math_function_test(funcname): - import random - import math - mathfn = getattr(math, funcname) - print funcname, - def fn(x): - return mathfn(x) - f = compile(fn, [float]) - for x in [0.12334, 0.3, 0.5, 0.9883]: - print x - assert (funcname, f(x)) == (funcname, mathfn(x)) - -def test_simple_math_functions(): - for funcname in simple_math_functions: - yield math_function_test, funcname - -def test_math_errors(): - import math - def fn(x): - return math.log(x) - f = compile(fn, [float]) - assert f(math.e) == math.log(math.e) - # this is a platform specific mess - def check(mathf, f, v): - try: - r = mathf(v) - except (OverflowError, ValueError), e: - #print mathf, v, e.__class__ - py.test.raises(e.__class__, f, v) - else: - if r != r: # nans - #print mathf, v, "NAN?", r - u = f(v) - assert u != u - else: - #print mathf, v, r - u = f(v) - assert u == r - - check(math.log, f, -1.0) - check(math.log, f, 0.0) - - def fmod1_0(y): - return math.fmod(1.0, y) - f = compile(fmod1_0, [float]) - check(fmod1_0, f, 0.0) - - def test_os_path_exists(): tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(): Added: pypy/trunk/pypy/translator/c/test/test_math.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/translator/c/test/test_math.py Wed Mar 17 12:19:47 2010 @@ -0,0 +1,42 @@ +import py, math +from pypy.module.math.test import test_direct +from pypy.translator.c.test.test_genc import compile + + +def get_test_case((fnname, args, expected)): + fn = getattr(math, fnname) + expect_valueerror = (expected == ValueError) + expect_overflowerror = (expected == OverflowError) + check = test_direct.get_tester(expected) + # + def testfn(): + try: + got = fn(*args) + except ValueError: + return expect_valueerror + except OverflowError: + return expect_overflowerror + else: + return check(got) + # + testfn.func_name = 'test_' + fnname + return testfn + + +testfnlist = [get_test_case(testcase) + for testcase in test_direct.MathTests.TESTCASES] + +def fn(): + for i in range(len(testfnlist)): + testfn = testfnlist[i] + if not testfn(): + return i + return -42 # ok + +def test_math(): + f = compile(fn, []) + res = f() + if res >= 0: + py.test.fail(repr(test_direct.MathTests.TESTCASES[res])) + else: + assert res == -42 From arigo at codespeak.net Wed Mar 17 12:23:01 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 12:23:01 +0100 (CET) Subject: [pypy-svn] r72302 - pypy/trunk/pypy/jit/backend/x86/test Message-ID: <20100317112301.E2B41282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 12:23:00 2010 New Revision: 72302 Added: pypy/trunk/pypy/jit/backend/x86/test/test_zmath.py - copied, changed from r72301, pypy/trunk/pypy/translator/c/test/test_math.py Log: Add a test for the SSE2 case too. Note that it has no effect on Windows so far. Copied: pypy/trunk/pypy/jit/backend/x86/test/test_zmath.py (from r72301, pypy/trunk/pypy/translator/c/test/test_math.py) ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_math.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_zmath.py Wed Mar 17 12:23:00 2010 @@ -1,6 +1,10 @@ +""" Test that the math module still behaves even when + compiled to C with SSE2 enabled. +""" import py, math from pypy.module.math.test import test_direct from pypy.translator.c.test.test_genc import compile +from pypy.jit.backend.x86.codebuf import ensure_sse2_floats def get_test_case((fnname, args, expected)): @@ -27,6 +31,7 @@ for testcase in test_direct.MathTests.TESTCASES] def fn(): + ensure_sse2_floats() for i in range(len(testfnlist)): testfn = testfnlist[i] if not testfn(): From arigo at codespeak.net Wed Mar 17 13:26:39 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 13:26:39 +0100 (CET) Subject: [pypy-svn] r72305 - pypy/trunk/pypy/rpython/module/test Message-ID: <20100317122639.EE372282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 13:26:38 2010 New Revision: 72305 Modified: pypy/trunk/pypy/rpython/module/test/test_ll_time.py Log: Improve the test. Modified: pypy/trunk/pypy/rpython/module/test/test_ll_time.py ============================================================================== --- pypy/trunk/pypy/rpython/module/test/test_ll_time.py (original) +++ pypy/trunk/pypy/rpython/module/test/test_ll_time.py Wed Mar 17 13:26:38 2010 @@ -35,11 +35,11 @@ # we can only subtract two numbers returned by the same function. # Moreover they might have different precisions, but it should # be at least 0.01 seconds, hence the sleeps. - assert 0 <= t2-t0 - assert 0 <= t3-t1 <= t4-t0 - assert 0 <= t4-t2 <= t5-t1 <= t6-t0 - assert 0 <= t5-t3 <= t6-t2 - assert 0 <= t6-t4 + assert 0.0199 <= t2-t0 <= 9.0 + assert 0.0199 <= t3-t1 <= t4-t0 <= 9.0 + assert 0.0199 <= t4-t2 <= t5-t1 <= t6-t0 <= 9.0 + assert 0.0199 <= t5-t3 <= t6-t2 <= 9.0 + assert 0.0199 <= t6-t4 <= 9.0 def test_time_sleep(self): def does_nothing(): From arigo at codespeak.net Wed Mar 17 13:30:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 13:30:29 +0100 (CET) Subject: [pypy-svn] r72306 - pypy/trunk/pypy/rpython/module/test Message-ID: <20100317123029.B463F282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 13:30:28 2010 New Revision: 72306 Modified: pypy/trunk/pypy/rpython/module/test/test_ll_time.py Log: Replace sleep() with a version that happily consumes CPU time, to make sure that time.clock() increase. Modified: pypy/trunk/pypy/rpython/module/test/test_ll_time.py ============================================================================== --- pypy/trunk/pypy/rpython/module/test/test_ll_time.py (original) +++ pypy/trunk/pypy/rpython/module/test/test_ll_time.py Wed Mar 17 13:30:28 2010 @@ -16,25 +16,30 @@ assert t0 <= res0 <= t1 <= res1 def test_time_clock(self): + def sleep(t): + # a version of time.sleep() that consumes actual CPU time + start = time.clock() + while abs(time.clock() - start) <= t: + pass def f(): return time.clock() t0 = time.clock() - time.sleep(0.011) + sleep(0.011) t1 = self.interpret(f, []) - time.sleep(0.011) + sleep(0.011) t2 = time.clock() - time.sleep(0.011) + sleep(0.011) t3 = self.interpret(f, []) - time.sleep(0.011) + sleep(0.011) t4 = time.clock() - time.sleep(0.011) + sleep(0.011) t5 = self.interpret(f, []) - time.sleep(0.011) + sleep(0.011) t6 = time.clock() # time.clock() and t1() might have a different notion of zero, so # we can only subtract two numbers returned by the same function. # Moreover they might have different precisions, but it should - # be at least 0.01 seconds, hence the sleeps. + # be at least 0.01 seconds, hence the "sleeps". assert 0.0199 <= t2-t0 <= 9.0 assert 0.0199 <= t3-t1 <= t4-t0 <= 9.0 assert 0.0199 <= t4-t2 <= t5-t1 <= t6-t0 <= 9.0 From arigo at codespeak.net Wed Mar 17 13:32:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 13:32:24 +0100 (CET) Subject: [pypy-svn] r72307 - pypy/trunk/pypy/rpython/module Message-ID: <20100317123224.8EF07282BDC@codespeak.net> Author: arigo Date: Wed Mar 17 13:32:23 2010 New Revision: 72307 Modified: pypy/trunk/pypy/rpython/module/ll_time.py Log: Include all headers also when looking for constants. Modified: pypy/trunk/pypy/rpython/module/ll_time.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_time.py (original) +++ pypy/trunk/pypy/rpython/module/ll_time.py Wed Mar 17 13:32:23 2010 @@ -42,7 +42,7 @@ class CConfigForFTime: _compilation_info_ = ExternalCompilationInfo( - includes=[TIME_H, 'sys/timeb.h'], + includes=includes, libraries=libraries ) TIMEB = platform.Struct(STRUCT_TIMEB, [('time', rffi.INT), From arigo at codespeak.net Wed Mar 17 14:01:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 14:01:40 +0100 (CET) Subject: [pypy-svn] r72308 - pypy/trunk/pypy/rpython/module Message-ID: <20100317130140.B2EEC282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 14:01:39 2010 New Revision: 72308 Modified: pypy/trunk/pypy/rpython/module/ll_time.py Log: Revert this, which was pointless. The real cause of the inconsistency between CLOCKS_PER_SEC in this test and in a complete pypy translation is due to including Python.h. Argggh. Modified: pypy/trunk/pypy/rpython/module/ll_time.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_time.py (original) +++ pypy/trunk/pypy/rpython/module/ll_time.py Wed Mar 17 14:01:39 2010 @@ -42,7 +42,7 @@ class CConfigForFTime: _compilation_info_ = ExternalCompilationInfo( - includes=includes, + includes=[TIME_H, 'sys/timeb.h'], libraries=libraries ) TIMEB = platform.Struct(STRUCT_TIMEB, [('time', rffi.INT), From arigo at codespeak.net Wed Mar 17 14:06:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 14:06:33 +0100 (CET) Subject: [pypy-svn] r72309 - pypy/trunk/pypy/rpython/lltypesystem/test Message-ID: <20100317130633.E6FD0282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 14:06:32 2010 New Revision: 72309 Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py Log: Kill this pointless line. Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py Wed Mar 17 14:06:32 2010 @@ -85,7 +85,6 @@ def test_string_reverse(self): c_source = py.code.Source(""" #include - #include #include char *f(char* arg) From arigo at codespeak.net Wed Mar 17 14:10:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 14:10:44 +0100 (CET) Subject: [pypy-svn] r72310 - pypy/branch/kill-python-h Message-ID: <20100317131044.16E9C282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 14:10:42 2010 New Revision: 72310 Added: pypy/branch/kill-python-h/ - copied from r72309, pypy/trunk/ Log: A branch in which to kill #include "Python.h". From arigo at codespeak.net Wed Mar 17 16:00:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 16:00:31 +0100 (CET) Subject: [pypy-svn] r72313 - in pypy/branch/kill-python-h/pypy: rlib rpython/module rpython/tool translator/c translator/c/src translator/tool Message-ID: <20100317150031.713BD282BDB@codespeak.net> Author: arigo Date: Wed Mar 17 16:00:29 2010 New Revision: 72313 Added: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h (contents, props changed) Modified: pypy/branch/kill-python-h/pypy/rlib/rmmap.py pypy/branch/kill-python-h/pypy/rpython/module/ll_os.py pypy/branch/kill-python-h/pypy/rpython/module/ll_os_stat.py pypy/branch/kill-python-h/pypy/rpython/tool/rffi_platform.py pypy/branch/kill-python-h/pypy/translator/c/genc.py pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h pypy/branch/kill-python-h/pypy/translator/c/src/main.h pypy/branch/kill-python-h/pypy/translator/c/src/obmalloc.c pypy/branch/kill-python-h/pypy/translator/tool/cbuild.py Log: Random whacking in order (originally) to remove the dependencies to Python.h or pyconfig.h. Modified: pypy/branch/kill-python-h/pypy/rlib/rmmap.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/rmmap.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/rmmap.py Wed Mar 17 16:00:29 2010 @@ -32,9 +32,10 @@ class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=includes, - pre_include_bits=['#ifndef _GNU_SOURCE\n' + - '#define _GNU_SOURCE\n' + - '#endif'] + #pre_include_bits=['#ifndef _GNU_SOURCE\n' + + # '#define _GNU_SOURCE\n' + + # '#endif'] + # ^^^ _GNU_SOURCE is always defined by the ExternalCompilationInfo now ) size_t = rffi_platform.SimpleType("size_t", rffi.LONG) off_t = rffi_platform.SimpleType("off_t", rffi.LONG) Modified: pypy/branch/kill-python-h/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/module/ll_os.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/module/ll_os.py Wed Mar 17 16:00:29 2010 @@ -88,31 +88,17 @@ def __init__(self): self.configure(CConfig) - # on some platforms, e.g. OS X Leopard, the following constants which - # may be defined in pyconfig.h triggers "legacy" behaviour for functions - # like setpgrp(): - # - # _POSIX_C_SOURCE 200112L - # _XOPEN_SOURCE 600 - # _DARWIN_C_SOURCE 1 - # - # since the translation currently includes pyconfig.h, the checkcompiles - # call below include the pyconfig.h file so that the same behaviour is - # present in both the check and the final translation... - if hasattr(os, 'getpgrp'): self.GETPGRP_HAVE_ARG = platform.checkcompiles( "getpgrp(0)", - '#include "pyconfig.h"\n#include ', - [platform.get_python_include_dir()] - ) + '#include ', + []) if hasattr(os, 'setpgrp'): self.SETPGRP_HAVE_ARG = platform.checkcompiles( "setpgrp(0,0)", - '#include "pyconfig.h"\n#include ', - [platform.get_python_include_dir()] - ) + '#include ', + []) # we need an indirection via c functions to get macro calls working on llvm XXX still? if hasattr(os, 'WCOREDUMP'): Modified: pypy/branch/kill-python-h/pypy/rpython/module/ll_os_stat.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/module/ll_os_stat.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/module/ll_os_stat.py Wed Mar 17 16:00:29 2010 @@ -136,7 +136,8 @@ compilation_info = ExternalCompilationInfo( # This must be set to 64 on some systems to enable large file support. - pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], + #pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], + # ^^^ nowadays it's always set in all C files we produce. includes = INCLUDES ) Modified: pypy/branch/kill-python-h/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/tool/rffi_platform.py Wed Mar 17 16:00:29 2010 @@ -8,7 +8,6 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import CompilationError from pypy.tool.udir import udir -import distutils # ____________________________________________________________ # @@ -18,7 +17,7 @@ if include_dirs is None: include_dirs = [] return ExternalCompilationInfo( - pre_include_bits=[c_header_source], + post_include_bits=[c_header_source], include_dirs=include_dirs ) @@ -563,11 +562,6 @@ # ____________________________________________________________ -def get_python_include_dir(): - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - return gcv.get('INCLUDEPY', '.') # this is for running on top of pypy-c - def configure_external_library(name, eci, configurations, symbol=None, _cache={}): """try to find the external library. Modified: pypy/branch/kill-python-h/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/genc.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/genc.py Wed Mar 17 16:00:29 2010 @@ -116,11 +116,8 @@ 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] + include_dirs = [pypy_include_dir] return ExternalCompilationInfo(include_dirs=include_dirs) def build_database(self): @@ -735,16 +732,7 @@ print >> f -def gen_size_check(f): - from pypy.rlib.rarithmetic import LONG_BIT - print >> f, '#if 8 * SIZEOF_LONG != %d' % (LONG_BIT,) - print >> f, '# error "C files are generated for a %d-bit platform"' % ( - LONG_BIT,) - print >> f, '#endif' - print >> f - def gen_structdef(f, database): - gen_size_check(f) structdeflist = database.getstructdeflist() print >> f, '/***********************************************************/' print >> f, '/*** Structure definitions ***/' @@ -830,6 +818,10 @@ print >> f, '\treturn error;' print >> f, '}' +def commondefs(defines): + from pypy.rlib.rarithmetic import LONG_BIT + defines['PYPY_LONG_BIT'] = LONG_BIT + def gen_source_standalone(database, modulename, targetdir, eci, entrypointname, defines={}): assert database.standalone @@ -845,16 +837,11 @@ # print >> f, '#include "common_header.h"' print >> f + commondefs(defines) defines['PYPY_STANDALONE'] = entrypointname for key, value in defines.items(): print >> fi, '#define %s %s' % (key, value) - if sys.platform == 'win32': - print >> fi, '#define Py_BUILD_CORE /* avoid pulling python libs in */' - print >> fi, '#define WIN32_LEAN_AND_MEAN /* winsock/winsock2 mess */' - - print >> fi, '#include "pyconfig.h"' - eci.write_c_header(fi) print >> fi, '#include "src/g_prerequisite.h"' @@ -902,14 +889,10 @@ # print >> f, '#include "common_header.h"' print >> f + commondefs(defines) for key, value in defines.items(): print >> fi, '#define %s %s' % (key, value) - if sys.platform == 'win32': - print >> fi, '#define WIN32_LEAN_AND_MEAN /* winsock/winsock2 mess */' - - print >> fi, '#include "pyconfig.h"' - eci.write_c_header(fi) print >> fi, '#include "src/g_prerequisite.h"' Added: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h ============================================================================== --- (empty file) +++ pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Wed Mar 17 16:00:29 2010 @@ -0,0 +1,75 @@ + +/************************************************************/ + /*** C header subsection: common types and macros ***/ + + +/* We only support the following two kinds of platform: + + int long long long void* + --32-bit-- 32 32 64 32 + --64-bit-- 32 64 64 64 + + In particular, Win64 is not supported because it has sizeof(long) == 4. + To fix this, find and review all the places that cast a pointer to a long. +*/ + +#include + +#if INT_MAX != 2147483647 +# error "unsupported value for INT_MAX" +#endif +#if INT_MIN != -2147483647-1 +# error "unsupported value for INT_MIN" +#endif + +#if LLONG_MAX != 9223372036854775807LL +# error "unsupported value for LLONG_MAX" +#endif +#if LLONG_MIN != -9223372036854775807LL-1LL +# error "unsupported value for LLONG_MIN" +#endif + + +/******************** 32-bit support ********************/ +#if PYPY_LONG_BIT == 32 + +# if LONG_MAX != 2147483647L +# error "error in LONG_MAX (32-bit sources but a 64-bit compiler?)" +# endif +# if LONG_MIN != -2147483647L-1L +# error "unsupported value for LONG_MIN" +# endif + +# define SIZEOF_INT 4 +# define SIZEOF_LONG 4 +# define SIZEOF_LONG_LONG 8 + +/******************** 64-bit support ********************/ +#else + +# if LONG_MAX != 9223372036854775807L +# error "error in LONG_MAX (64-bit sources but a 32-bit compiler?)" +# endif +# if LONG_MIN != -9223372036854775807L-1L +# error "unsupported value for LONG_MIN" +# endif + +# define SIZEOF_INT 4 +# define SIZEOF_LONG 8 +# define SIZEOF_LONG_LONG 8 + +#endif + +/********************************************************/ + +typedef long Py_intptr_t; +typedef unsigned long Py_uintptr_t; + +#if ((-1) >> 1) > 0 +# define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ + ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J)) +#elif ((-1) >> 1) == -1 +# define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) +#else +# error "uh? strange result" +#endif Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h Wed Mar 17 16:00:29 2010 @@ -2,19 +2,9 @@ /**************************************************************/ /*** this is included before any code produced by genc.py ***/ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* this must be defined before including other headers - in order to get a few extra functions like mremap() */ -#endif +#include "src/commondefs.h" -/* XXX for now we always include Python.h even to produce stand-alone - * executables (which are *not* linked against CPython then), - * to get the convenient macro definitions - */ #ifndef AVR -#include "Python.h" - - #include "thread.h" /* needs to be included early to define the struct RPyOpaque_ThreadLock */ #endif Modified: pypy/branch/kill-python-h/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/main.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/main.h Wed Mar 17 16:00:29 2010 @@ -23,6 +23,12 @@ instrument_setup(); + if (sizeof(void*) != SIZEOF_LONG) { + errmsg = "only support platforms where sizeof(void*) == sizeof(long)," + " for now"; + goto error; + } + errmsg = RPython_StartupCode(); if (errmsg) goto error; Modified: pypy/branch/kill-python-h/pypy/translator/c/src/obmalloc.c ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/obmalloc.c (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/obmalloc.c Wed Mar 17 16:00:29 2010 @@ -1,4 +1,3 @@ -#include "Python.h" #ifdef WITH_PYMALLOC Modified: pypy/branch/kill-python-h/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/kill-python-h/pypy/translator/tool/cbuild.py Wed Mar 17 16:00:29 2010 @@ -225,6 +225,7 @@ return ExternalCompilationInfo(**attrs) def write_c_header(self, fileobj): + print >> fileobj, STANDARD_DEFINES for piece in self.pre_include_bits: print >> fileobj, piece for path in self.includes: @@ -254,8 +255,6 @@ f = filename.open("w") if being_main: f.write("#define PYPY_NOT_MAIN_FILE\n") - if sys.platform == 'win32': - f.write("#define WIN32_LEAN_AND_MEAN\n") self.write_c_header(f) source = str(source) f.write(source) @@ -292,3 +291,28 @@ d['separate_module_files'] = () d['separate_module_sources'] = () return ExternalCompilationInfo(**d) + + +# ____________________________________________________________ +# +# This is extracted from pyconfig.h from CPython. It sets the macros +# that affect the features we get from system include files. + +STANDARD_DEFINES = ''' +/* Define on Darwin to activate all library features */ +#define _DARWIN_C_SOURCE 1 +/* This must be set to 64 on some systems to enable large file support. */ +#define _FILE_OFFSET_BITS 64 +/* Define on Linux to activate all library features */ +#define _GNU_SOURCE 1 +/* This must be defined on some systems to enable large file support. */ +#define _LARGEFILE_SOURCE 1 +/* Define on NetBSD to activate all library features */ +#define _NETBSD_SOURCE 1 +/* Define to activate features from IEEE Stds 1003.1-2001 */ +#define _POSIX_C_SOURCE 200112L +/* Define on FreeBSD to activate all library features */ +#define __BSD_VISIBLE 1 +/* Windows: winsock/winsock2 mess */ +#define WIN32_LEAN_AND_MEAN +''' From afa at codespeak.net Wed Mar 17 16:29:35 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 17 Mar 2010 16:29:35 +0100 (CET) Subject: [pypy-svn] r72315 - pypy/branch/kill-python-h/pypy/rpython/module Message-ID: <20100317152935.93F83282BDD@codespeak.net> Author: afa Date: Wed Mar 17 16:29:34 2010 New Revision: 72315 Modified: pypy/branch/kill-python-h/pypy/rpython/module/ll_time.py Log: On windows, struct timeval is defined in winsock.h or winsock2.h. It is needed now, probably because the #define WIN32_LEAN_AND_MEAN was moved. Modified: pypy/branch/kill-python-h/pypy/rpython/module/ll_time.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/module/ll_time.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/module/ll_time.py Wed Mar 17 16:29:34 2010 @@ -15,7 +15,8 @@ TIME_H = 'time.h' FTIME = '_ftime64' STRUCT_TIMEB = 'struct __timeb64' - includes = [TIME_H, 'windows.h', 'sys/types.h', 'sys/timeb.h'] + includes = ['winsock2.h', 'windows.h', + TIME_H, 'sys/types.h', 'sys/timeb.h'] else: TIME_H = 'sys/time.h' FTIME = 'ftime' From arigo at codespeak.net Wed Mar 17 17:37:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 17:37:08 +0100 (CET) Subject: [pypy-svn] r72318 - in pypy/branch/kill-python-h/pypy/interpreter: . test Message-ID: <20100317163708.9E9CF282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 17:37:07 2010 New Revision: 72318 Modified: pypy/branch/kill-python-h/pypy/interpreter/pycode.py pypy/branch/kill-python-h/pypy/interpreter/test/test_function.py Log: Test and fix: (lambda: 42) should not have any docstring. Modified: pypy/branch/kill-python-h/pypy/interpreter/pycode.py ============================================================================== --- pypy/branch/kill-python-h/pypy/interpreter/pycode.py (original) +++ pypy/branch/kill-python-h/pypy/interpreter/pycode.py Wed Mar 17 17:37:07 2010 @@ -220,9 +220,11 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty - return self.co_consts_w[0] - else: - return space.w_None + w_doc = self.co_consts_w[0] + if (space.is_true(space.isinstance(w_doc, space.w_str)) or + space.is_true(space.isinstance(w_doc, space.w_unicode))): + return w_doc + return space.w_None def getjoinpoints(self): """Compute the bytecode positions that are potential join points Modified: pypy/branch/kill-python-h/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/branch/kill-python-h/pypy/interpreter/test/test_function.py (original) +++ pypy/branch/kill-python-h/pypy/interpreter/test/test_function.py Wed Mar 17 17:37:07 2010 @@ -281,6 +281,14 @@ raises(TypeError, type, 'Foo', (type(f),), {}) raises(TypeError, type, 'Foo', (type(len),), {}) + def test_lambda_docstring(self): + # Like CPython, (lambda:"foo") has a docstring of "foo". + # But let's not test that. Just test that (lambda:42) does not + # have 42 as docstring. + f = lambda: 42 + assert f.func_doc is None + + class AppTestMethod: def test_simple_call(self): class A(object): From arigo at codespeak.net Wed Mar 17 17:50:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 17:50:16 +0100 (CET) Subject: [pypy-svn] r72320 - pypy/branch/kill-python-h/pypy/translator/c/test Message-ID: <20100317165016.12D61282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 17:50:14 2010 New Revision: 72320 Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py Log: Turn this test into a standalone test. Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py Wed Mar 17 17:50:14 2010 @@ -1,6 +1,6 @@ import py, math from pypy.module.math.test import test_direct -from pypy.translator.c.test.test_genc import compile +from pypy.translator.c.test.test_standalone import StandaloneTests def get_test_case((fnname, args, expected)): @@ -25,18 +25,25 @@ testfnlist = [get_test_case(testcase) for testcase in test_direct.MathTests.TESTCASES] +reprlist = [repr(testcase) + for testcase in test_direct.MathTests.TESTCASES] -def fn(): +def fn(args): + err = False for i in range(len(testfnlist)): testfn = testfnlist[i] if not testfn(): - return i - return -42 # ok - -def test_math(): - f = compile(fn, []) - res = f() - if res >= 0: - py.test.fail(repr(test_direct.MathTests.TESTCASES[res])) - else: - assert res == -42 + print "error:", reprlist[i] + err = True + if not err: + print "all ok" + return 0 + +class TestMath(StandaloneTests): + def test_math(self): + t, cbuilder = self.compile(fn) + data = cbuilder.cmdexec('') + if "error:" in data: + py.test.fail(data.strip()) + else: + assert "all ok" in data From arigo at codespeak.net Wed Mar 17 17:59:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 17:59:38 +0100 (CET) Subject: [pypy-svn] r72321 - pypy/branch/kill-python-h/pypy/translator/c/test Message-ID: <20100317165938.C05E0282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 17:59:37 2010 New Revision: 72321 Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py Log: Finally: test both the non-optimized and the optimized case. Finds a bug when the test itself runs on top of pypy-c. Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/test/test_math.py Wed Mar 17 17:59:37 2010 @@ -39,11 +39,16 @@ print "all ok" return 0 + class TestMath(StandaloneTests): - def test_math(self): - t, cbuilder = self.compile(fn) + + def test_math(self, debug=True): + t, cbuilder = self.compile(fn, debug=debug) data = cbuilder.cmdexec('') if "error:" in data: py.test.fail(data.strip()) else: assert "all ok" in data + + def test_math_nodebug(self): + self.test_math(debug=False) From arigo at codespeak.net Wed Mar 17 18:25:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 18:25:09 +0100 (CET) Subject: [pypy-svn] r72323 - in pypy/branch/kill-python-h/pypy/translator/c: . src Message-ID: <20100317172509.10F30282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 18:25:08 2010 New Revision: 72323 Modified: pypy/branch/kill-python-h/pypy/translator/c/genc.py pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h Log: Fix for the case of non-standalone builds. Modified: pypy/branch/kill-python-h/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/genc.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/genc.py Wed Mar 17 18:25:08 2010 @@ -115,7 +115,6 @@ self.eci = self.get_eci() def get_eci(self): - from distutils import sysconfig pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') include_dirs = [pypy_include_dir] return ExternalCompilationInfo(include_dirs=include_dirs) @@ -303,6 +302,12 @@ _module = None _wrapper = None + def get_eci(self): + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() + eci = ExternalCompilationInfo(include_dirs=[python_inc]) + return eci.merge(CBuilder.get_eci(self)) + def getentrypointptr(self): # xxx if self._wrapper is None: self._wrapper = new_wrapper(self.entrypoint, self.translator) Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h Wed Mar 17 18:25:08 2010 @@ -2,7 +2,13 @@ /**************************************************************/ /*** this is included before any code produced by genc.py ***/ -#include "src/commondefs.h" + +#ifdef PYPY_STANDALONE +# include "src/commondefs.h" +#else +# include "Python.h" +#endif + #ifndef AVR #include "thread.h" /* needs to be included early to define the From arigo at codespeak.net Wed Mar 17 18:26:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 18:26:49 +0100 (CET) Subject: [pypy-svn] r72324 - pypy/branch/kill-python-h/pypy/translator/c/src Message-ID: <20100317172649.3F87B282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 18:26:47 2010 New Revision: 72324 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Log: Add a missing def. Modified: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Wed Mar 17 18:26:47 2010 @@ -73,3 +73,5 @@ #else # error "uh? strange result" #endif + +#define Py_HUGE_VAL HUGE_VAL From fijal at codespeak.net Wed Mar 17 18:35:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 17 Mar 2010 18:35:34 +0100 (CET) Subject: [pypy-svn] r72326 - pypy/build/bot2/pypybuildbot Message-ID: <20100317173534.C7E58282BDD@codespeak.net> Author: fijal Date: Wed Mar 17 18:35:33 2010 New Revision: 72326 Modified: pypy/build/bot2/pypybuildbot/builds.py pypy/build/bot2/pypybuildbot/master.py Log: Try to upload nightly builds. As usual with buildbot, unsure... Also make platform=osx on mac, to make executable name different Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Wed Mar 17 18:35:33 2010 @@ -109,10 +109,16 @@ logfiles={'pytestLog': 'cpython.log'})) if pypyjit: + # upload nightly build, if we're running jit tests + nightly = 'nightly/pypy-c-jit-%(got_revision)s-' + platform + pypy_c_rel = 'pypy/translator/goal/pypy-c' + self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, + masterdest=WithProperties(nightly), + workdir='.')) self.addStep(ShellCmd( description="pypyjit tests", command=["python", "pypy/test_all.py", - "--pypy=pypy/translator/goal/pypy-c", + "--pypy=" + pypy_c_rel, "--resultlog=pypyjit.log", "pypy/module/pypyjit/test"], logfiles={'pytestLog': 'pypyjit.log'})) @@ -128,10 +134,11 @@ 'benchmarks'], workdir='.')) self.addStep(Translate(['-Ojit'], [])) + pypy_c_rel = "../build/pypy/translator/goal/pypy-c" self.addStep(ShellCmd( description="run more benchmarks on top of pypy-c-jit", command=["python", "runner.py", '--output-filename', 'result.json', - '--pypy-c', '../build/pypy/translator/goal/pypy-c', + '--pypy-c', pypy_c_rel, '--upload', '--force-host', 'bigdog', '--revision', WithProperties('%(got_revision)s'), '--branch', WithProperties('%(branch)s')], Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Mar 17 18:35:33 2010 @@ -79,6 +79,15 @@ app_tests=True, ) +pypyJITTranslatedTestFactoryOSX = pypybuilds.Translated( + platform='osx' + translationArgs=jit_translation_args, + targetArgs=[], + lib_python=True, + pypyjit=True, + app_tests=True, + ) + pypyJITTranslatedTestFactoryWin = pypybuilds.Translated( platform="win32", translationArgs=jit_translation_args, @@ -185,7 +194,7 @@ {"name" : JITMACOSX32, "slavenames": ["minime"], 'builddir' : JITMACOSX32, - 'factory' : pypyJITTranslatedTestFactory, + 'factory' : pypyJITTranslatedTestFactoryOSX, 'category' : 'jit', }, {"name" : JITWIN32, From fijal at codespeak.net Wed Mar 17 18:37:27 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 17 Mar 2010 18:37:27 +0100 (CET) Subject: [pypy-svn] r72327 - pypy/build/bot2/pypybuildbot Message-ID: <20100317173727.C4F98282BDD@codespeak.net> Author: fijal Date: Wed Mar 17 18:37:25 2010 New Revision: 72327 Modified: pypy/build/bot2/pypybuildbot/master.py Log: A killer coma Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Wed Mar 17 18:37:25 2010 @@ -80,7 +80,7 @@ ) pypyJITTranslatedTestFactoryOSX = pypybuilds.Translated( - platform='osx' + platform='osx', translationArgs=jit_translation_args, targetArgs=[], lib_python=True, From afa at codespeak.net Wed Mar 17 18:49:02 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 17 Mar 2010 18:49:02 +0100 (CET) Subject: [pypy-svn] r72328 - pypy/branch/kill-python-h/pypy/translator/c/src Message-ID: <20100317174902.3142A282BDD@codespeak.net> Author: afa Date: Wed Mar 17 18:49:00 2010 New Revision: 72328 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/support.h Log: Fix compilation on windows (stderr was undefined) Modified: pypy/branch/kill-python-h/pypy/translator/c/src/support.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/support.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/support.h Wed Mar 17 18:49:00 2010 @@ -2,6 +2,7 @@ /************************************************************/ /*** C header subsection: support functions ***/ +#include /*** misc ***/ From arigo at codespeak.net Wed Mar 17 18:53:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 18:53:49 +0100 (CET) Subject: [pypy-svn] r72329 - in pypy/branch/kill-python-h/pypy: rlib translator/c/src Message-ID: <20100317175349.6F75E282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 18:53:47 2010 New Revision: 72329 Removed: pypy/branch/kill-python-h/pypy/translator/c/src/addrinfo.h pypy/branch/kill-python-h/pypy/translator/c/src/getaddrinfo.c pypy/branch/kill-python-h/pypy/translator/c/src/getnameinfo.c Modified: pypy/branch/kill-python-h/pypy/rlib/getnameinfo.py Log: Kill three obsolete C files. Fix the docstring in the replacement RPython module. Modified: pypy/branch/kill-python-h/pypy/rlib/getnameinfo.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/getnameinfo.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/getnameinfo.py Wed Mar 17 18:53:47 2010 @@ -1,6 +1,6 @@ """ An RPython implementation of getnameinfo(). -This is a rewrite of the CPython source: Modules/getaddrinfo.c +This is a rewrite of the CPython source: Modules/getnameinfo.c """ from pypy.rlib import _rsocket_rffi as _c from pypy.rlib.rsocket import RSocketError, GAIError From arigo at codespeak.net Wed Mar 17 19:19:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 17 Mar 2010 19:19:32 +0100 (CET) Subject: [pypy-svn] r72330 - pypy/branch/kill-python-h/pypy/translator/c/src Message-ID: <20100317181932.B002E282BDD@codespeak.net> Author: arigo Date: Wed Mar 17 19:19:28 2010 New Revision: 72330 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Log: Add HAVE_LONG_LONG, which is always the case for us. Modified: pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Wed Mar 17 19:19:28 2010 @@ -74,4 +74,5 @@ # error "uh? strange result" #endif +#define HAVE_LONG_LONG 1 #define Py_HUGE_VAL HUGE_VAL From fijal at codespeak.net Wed Mar 17 19:24:32 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 17 Mar 2010 19:24:32 +0100 (CET) Subject: [pypy-svn] r72331 - in pypy/trunk/pypy: config doc/config translator/c translator/platform Message-ID: <20100317182432.13AF7282BDD@codespeak.net> Author: fijal Date: Wed Mar 17 19:24:31 2010 New Revision: 72331 Added: pypy/trunk/pypy/doc/config/translation.force_make.txt (contents, props changed) pypy/trunk/pypy/doc/config/translation.make_jobs.txt (contents, props changed) Modified: pypy/trunk/pypy/config/translationoption.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/platform/posix.py Log: Add a way to pass -j x to make. I always wanted to do this :-) Additionally add --force-make that would call make no matter what. Unfortunately IntOption can't depend on anything so no requirement so far :( Modified: pypy/trunk/pypy/config/translationoption.py ============================================================================== --- pypy/trunk/pypy/config/translationoption.py (original) +++ pypy/trunk/pypy/config/translationoption.py Wed Mar 17 19:24:31 2010 @@ -154,6 +154,12 @@ cmdline="--cflags"), StrOption("linkerflags", "Specify flags for the linker (C backend only)", cmdline="--ldflags"), + BoolOption("force_make", "Force execution of makefile instead of" + " calling platform", cmdline="--force-make", + default=False, negation=False), + IntOption("make_jobs", "Specify -j argument to make for compilation" + " (C backend only)", + cmdline="--make-jobs", default=1), # Flags of the TranslationContext: BoolOption("simplifying", "Simplify flow graphs", default=True), Added: pypy/trunk/pypy/doc/config/translation.force_make.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/translation.force_make.txt Wed Mar 17 19:24:31 2010 @@ -0,0 +1 @@ +Force executing makefile instead of using platform. Added: pypy/trunk/pypy/doc/config/translation.make_jobs.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/translation.make_jobs.txt Wed Mar 17 19:24:31 2010 @@ -0,0 +1 @@ +Specify number of make jobs for make command. Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Wed Mar 17 19:24:31 2010 @@ -448,8 +448,13 @@ def compile(self): assert self.c_source_filename assert not self._compiled - if self.config.translation.gcrootfinder == "asmgcc": - self.translator.platform.execute_makefile(self.targetdir) + if (self.config.translation.gcrootfinder == "asmgcc" or + self.config.translation.force_make): + extra_opts = [] + if self.config.translation.make_jobs != 1: + extra_opts += ['-j', str(self.config.translation.make_jobs)] + self.translator.platform.execute_makefile(self.targetdir, + extra_opts) else: compiler = CCompilerDriver(self.translator.platform, [self.c_source_filename] + self.extrafiles, Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Wed Mar 17 19:24:31 2010 @@ -109,13 +109,13 @@ return m - def execute_makefile(self, path_to_makefile): + def execute_makefile(self, path_to_makefile, extra_opts=[]): 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(self.make_cmd, ['-C', str(path)]) + log.execute('make %s in %s' % (" ".join(extra_opts), path)) + returncode, stdout, stderr = _run_subprocess(self.make_cmd, ['-C', str(path)] + extra_opts) self._handle_error(returncode, stdout, stderr, path.join('make')) class Definition(object): From fijal at codespeak.net Wed Mar 17 19:45:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 17 Mar 2010 19:45:51 +0100 (CET) Subject: [pypy-svn] r72332 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100317184551.EF729282BDD@codespeak.net> Author: fijal Date: Wed Mar 17 19:45:50 2010 New Revision: 72332 Added: pypy/extradoc/talk/oopsla2010/paper2.txt (contents, props changed) Log: Start writing down a paper, second approach Added: pypy/extradoc/talk/oopsla2010/paper2.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/oopsla2010/paper2.txt Wed Mar 17 19:45:50 2010 @@ -0,0 +1,57 @@ +Problem domain +============== + +Python, as well as other dynamic languages to varying extend, provides a way +to dynamically introspect the frame stack of running program. The dynamism +of Python language makes it impossible to statically detect all the cases +in which a program can introspect the framestack. Most operations can +execute arbitrary python code (including frame introspection code) and +types are not known until runtime. XXX cite brett cannon about localized +type inference. + +The nature of the way how the framestack is exposed, makes it impossible to +perform common optimizations, like escape analysis (all local variables escape +through frame object) or inlining (all frames are required to be present on +framestack). + +Idea +==== + +In this paper we present a way to use the processor (or C) stack together +with bookkeeping information that can lazily reconstruct the python framestack +from processor stack, preserving all the necessary information. Our approach +assumes that we have both the just in time compiler that compiles efficient +code, that can fall back to interpreter in case of frame forcing. In theory, +this approach can be implemented also with static compilation of python +language, but the duality of efficiently compiled and interpreted (or much +less efficiently compiled) needs to be preserved. The whole idea revolves +around three basic concepts: + +* Virtualizables - frames that are allocated on the heap, but have fields + living on the processor stack that are lazily moved over to heap in case + of a direct access. This means even though frames has to be allocated, + they don't present any further overhead. + +* Virtual frames - frames that are known not to escape, except via framestack + (special objects called virtual refs explained below). They present no + overhead. + +* Virtual refs - special objects that can reference frames without escaping + them, used for frame chaining. + +We present benchmarks for both the small toy language that presents frame +introspection capabilities as well as results for the python language. + +Our work revolves primarily around tracing just in time compiler infrastructure, +that we wrote (XXX cite). While the idea is not tied directly to the JIT, +it feels far more natural due to the dual-nature of compiler (JIT-compiled +efficient code and fully frame-aware, much slower interpreter). There are +other reasons why we chose JIT, notably the fact that inlining in static setting +is proven to be very hard for the Python language (since anyone can change +global namespace via which function objects are referenced). + +Benchmarks +========== + +XXX actually write down the toy languages + From fijal at codespeak.net Wed Mar 17 20:47:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 17 Mar 2010 20:47:14 +0100 (CET) Subject: [pypy-svn] r72333 - pypy/build/bot2/pypybuildbot Message-ID: <20100317194714.85953282BDD@codespeak.net> Author: fijal Date: Wed Mar 17 20:47:12 2010 New Revision: 72333 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: fix paths (?) Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Wed Mar 17 20:47:12 2010 @@ -111,14 +111,14 @@ if pypyjit: # upload nightly build, if we're running jit tests nightly = 'nightly/pypy-c-jit-%(got_revision)s-' + platform - pypy_c_rel = 'pypy/translator/goal/pypy-c' + pypy_c_rel = 'build/pypy/translator/goal/pypy-c' self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, masterdest=WithProperties(nightly), workdir='.')) self.addStep(ShellCmd( description="pypyjit tests", command=["python", "pypy/test_all.py", - "--pypy=" + pypy_c_rel, + "--pypy=pypy/translator/goal/pypy-c", "--resultlog=pypyjit.log", "pypy/module/pypyjit/test"], logfiles={'pytestLog': 'pypyjit.log'})) From benjamin at codespeak.net Wed Mar 17 22:09:06 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 17 Mar 2010 22:09:06 +0100 (CET) Subject: [pypy-svn] r72335 - pypy/trunk/pypy/jit/metainterp Message-ID: <20100317210906.65E8F282BDC@codespeak.net> Author: benjamin Date: Wed Mar 17 22:09:04 2010 New Revision: 72335 Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py Log: remove old statement Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py ============================================================================== --- pypy/trunk/pypy/jit/metainterp/codewriter.py (original) +++ pypy/trunk/pypy/jit/metainterp/codewriter.py Wed Mar 17 22:09:04 2010 @@ -475,7 +475,6 @@ for arg in self.force_block_args_order(block): self.register_var(arg, verbose=False) self.emit(label(block)) - #self.make_prologue(block) operations = block.operations if block.exitswitch == c_last_exception: From fijal at codespeak.net Thu Mar 18 00:14:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 00:14:33 +0100 (CET) Subject: [pypy-svn] r72336 - pypy/build/bot2/pypybuildbot Message-ID: <20100317231433.01218282BDC@codespeak.net> Author: fijal Date: Thu Mar 18 00:14:32 2010 New Revision: 72336 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: provide a full path Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Mar 18 00:14:32 2010 @@ -110,7 +110,7 @@ if pypyjit: # upload nightly build, if we're running jit tests - nightly = 'nightly/pypy-c-jit-%(got_revision)s-' + platform + nightly = os.path.expanduser('~/nightly/pypy-c-jit-%(got_revision)s-' + platform) pypy_c_rel = 'build/pypy/translator/goal/pypy-c' self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, masterdest=WithProperties(nightly), From fijal at codespeak.net Thu Mar 18 01:09:12 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 01:09:12 +0100 (CET) Subject: [pypy-svn] r72337 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100318000912.A32C3282BDC@codespeak.net> Author: fijal Date: Thu Mar 18 01:09:09 2010 New Revision: 72337 Added: pypy/extradoc/talk/oopsla2010/related_work.txt (contents, props changed) Modified: pypy/extradoc/talk/oopsla2010/paper.txt Log: a related work stuff Modified: pypy/extradoc/talk/oopsla2010/paper.txt ============================================================================== --- pypy/extradoc/talk/oopsla2010/paper.txt (original) +++ pypy/extradoc/talk/oopsla2010/paper.txt Thu Mar 18 01:09:09 2010 @@ -13,6 +13,8 @@ XXX use an API to manipulate that. I'm not sure if it's really the problem XXX since we do the same on assembler stack + + Approach ======== Added: pypy/extradoc/talk/oopsla2010/related_work.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/oopsla2010/related_work.txt Thu Mar 18 01:09:09 2010 @@ -0,0 +1,17 @@ +Hotspot's deoptimizer +===================== + +It works in surprisingly related manner. The main differences are: +a) we have it structured, so it's not that messy and ad-hoc (I think) +b) we have less separation between debugger and user program +c) we don't know how long we need to keep stuff alive + +Smalltalk +========= + +I'm not aware of frame introspection capabilities in smalltalk + +Psyco +===== + +??? From benjamin at codespeak.net Thu Mar 18 01:55:45 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 01:55:45 +0100 (CET) Subject: [pypy-svn] r72338 - in pypy/trunk/pypy/interpreter: . astcompiler astcompiler/test Message-ID: <20100318005545.34766282BDE@codespeak.net> Author: benjamin Date: Thu Mar 18 01:55:43 2010 New Revision: 72338 Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py pypy/trunk/pypy/interpreter/pycode.py Log: don't allow lambdas to have docstrings and prevent non-strings from becoming docstrings Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/codegen.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/codegen.py Thu Mar 18 01:55:43 2010 @@ -1289,6 +1289,8 @@ if lam.args.args: self._handle_nested_args(lam.args.args) self.argcount = len(lam.args.args) + # Prevent a string from being the first constant and thus a docstring. + self.add_const(self.space.w_None) lam.body.walkabout(self) self.emit_op(ops.RETURN_VALUE) 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 Thu Mar 18 01:55:43 2010 @@ -317,6 +317,9 @@ for source, expected in [ ('''def foo(): return 1''', None), ('''class foo: pass''', None), + ('''foo = lambda: 4''', None), + ('''foo = lambda: "foo"''', None), + ('''def foo(): 4''', None), ('''class foo: "foo"''', "foo"), ('''def foo(): """foo docstring""" Modified: pypy/trunk/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pycode.py (original) +++ pypy/trunk/pypy/interpreter/pycode.py Thu Mar 18 01:55:43 2010 @@ -220,9 +220,10 @@ def getdocstring(self, space): if self.co_consts_w: # it is probably never empty - return self.co_consts_w[0] - else: - return space.w_None + w_first = self.co_consts_w[0] + if space.is_true(space.isinstance(w_first, space.w_basestring)): + return w_first + return space.w_None def getjoinpoints(self): """Compute the bytecode positions that are potential join points From benjamin at codespeak.net Thu Mar 18 02:07:30 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 02:07:30 +0100 (CET) Subject: [pypy-svn] r72339 - pypy/trunk/pypy/interpreter/astcompiler Message-ID: <20100318010730.7FFFF282BDE@codespeak.net> Author: benjamin Date: Thu Mar 18 02:07:28 2010 New Revision: 72339 Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py Log: adding None here isn't required Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/codegen.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/codegen.py Thu Mar 18 02:07:28 2010 @@ -1273,7 +1273,6 @@ self.add_const(doc_str.s) start = 1 else: - self.add_const(self.space.w_None) start = 0 if func.args.args: self._handle_nested_args(func.args.args) From benjamin at codespeak.net Thu Mar 18 02:28:00 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 02:28:00 +0100 (CET) Subject: [pypy-svn] r72340 - pypy/trunk/pypy/interpreter/astcompiler Message-ID: <20100318012800.E7965282BDE@codespeak.net> Author: benjamin Date: Thu Mar 18 02:27:59 2010 New Revision: 72340 Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py Log: refactor docstring code to require less ugly asserts Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/codegen.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/codegen.py Thu Mar 18 02:27:59 2010 @@ -196,8 +196,12 @@ op = name_ops_default(ctx) self.emit_op_arg(op, self.add_name(container, identifier)) - def is_docstring(self, node): - return isinstance(node, ast.Expr) and isinstance(node.value, ast.Str) + def possible_docstring(self, node): + if isinstance(node, ast.Expr): + expr_value = node.value + if isinstance(expr_value, ast.Str): + return expr_value + return None def _get_code_flags(self): # Default for everything but module scopes. @@ -207,11 +211,10 @@ """Compile a list of statements, handling doc strings if needed.""" if body: start = 0 - if self.is_docstring(body[0]): - doc_expr = body[0] - assert isinstance(doc_expr, ast.Expr) + doc_expr = self.possible_docstring(body[0]) + if doc_expr is not None: start = 1 - doc_expr.value.walkabout(self) + doc_expr.walkabout(self) self.name_op("__doc__", ast.Store) for i in range(start, len(body)): body[i].walkabout(self) @@ -1265,12 +1268,9 @@ def _compile(self, func): assert isinstance(func, ast.FunctionDef) # If there's a docstring, store it as the first constant. - if self.is_docstring(func.body[0]): - doc_expr = func.body[0] - assert isinstance(doc_expr, ast.Expr) - doc_str = doc_expr.value - assert isinstance(doc_str, ast.Str) - self.add_const(doc_str.s) + doc_expr = self.possible_docstring(func.body[0]) + if doc_expr is not None: + self.add_const(doc_expr.s) start = 1 else: start = 0 From benjamin at codespeak.net Thu Mar 18 03:29:15 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 03:29:15 +0100 (CET) Subject: [pypy-svn] r72341 - pypy/trunk/pypy/interpreter/astcompiler Message-ID: <20100318022915.5F704282BDE@codespeak.net> Author: benjamin Date: Thu Mar 18 03:29:13 2010 New Revision: 72341 Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py Log: revert r72339; some cpython tests require a None constant Modified: pypy/trunk/pypy/interpreter/astcompiler/codegen.py ============================================================================== --- pypy/trunk/pypy/interpreter/astcompiler/codegen.py (original) +++ pypy/trunk/pypy/interpreter/astcompiler/codegen.py Thu Mar 18 03:29:13 2010 @@ -1273,6 +1273,7 @@ self.add_const(doc_expr.s) start = 1 else: + self.add_const(self.space.w_None) start = 0 if func.args.args: self._handle_nested_args(func.args.args) From benjamin at codespeak.net Thu Mar 18 03:44:04 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 03:44:04 +0100 (CET) Subject: [pypy-svn] r72342 - in pypy/trunk/pypy: interpreter objspace/flow Message-ID: <20100318024404.90351282BDE@codespeak.net> Author: benjamin Date: Thu Mar 18 03:44:03 2010 New Revision: 72342 Modified: pypy/trunk/pypy/interpreter/pycode.py pypy/trunk/pypy/objspace/flow/flowcontext.py Log: remove unused getjoinpoints() method Modified: pypy/trunk/pypy/interpreter/pycode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pycode.py (original) +++ pypy/trunk/pypy/interpreter/pycode.py Thu Mar 18 03:44:03 2010 @@ -225,12 +225,6 @@ return w_first return space.w_None - def getjoinpoints(self): - """Compute the bytecode positions that are potential join points - (for FlowObjSpace)""" - # first approximation - return dis.findlabels(self.co_code) - def _to_code(self): """For debugging only.""" consts = [None] * len(self.co_consts_w) Modified: pypy/trunk/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/flowcontext.py (original) +++ pypy/trunk/pypy/objspace/flow/flowcontext.py Thu Mar 18 03:44:03 2010 @@ -209,8 +209,6 @@ arg_list[position] = Constant(value) frame.setfastscope(arg_list) self.joinpoints = {} - #for joinpoint in code.getjoinpoints(): - # self.joinpoints[joinpoint] = [] # list of blocks initialblock = SpamBlock(FrameState(frame).copy()) self.pendingblocks = collections.deque([initialblock]) self.graph = FunctionGraph(name or code.co_name, initialblock) From xoraxax at codespeak.net Thu Mar 18 04:34:08 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 04:34:08 +0100 (CET) Subject: [pypy-svn] r72343 - in pypy/trunk/pypy/module: __pypy__ __pypy__/test _collections Message-ID: <20100318033408.2739F282BDE@codespeak.net> Author: xoraxax Date: Thu Mar 18 04:34:06 2010 New Revision: 72343 Added: pypy/trunk/pypy/module/__pypy__/interp_identitydict.py - copied unchanged from r72307, pypy/trunk/pypy/module/_collections/interp_collection.py pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py - copied, changed from r72307, pypy/trunk/pypy/module/_collections/test/test_collection.py Removed: pypy/trunk/pypy/module/_collections/ Modified: pypy/trunk/pypy/module/__pypy__/__init__.py Log: Move identity dict from _collections to __pypy__. Modified: pypy/trunk/pypy/module/__pypy__/__init__.py ============================================================================== --- pypy/trunk/pypy/module/__pypy__/__init__.py (original) +++ pypy/trunk/pypy/module/__pypy__/__init__.py Thu Mar 18 04:34:06 2010 @@ -10,6 +10,7 @@ interpleveldefs = { 'internal_repr' : 'interp_magic.internal_repr', 'bytebuffer' : 'bytebuffer.bytebuffer', + 'identity_dict' : 'interp_identitydict.W_IdentityDict', } def setup_after_space_initialization(self): Copied: pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py (from r72307, pypy/trunk/pypy/module/_collections/test/test_collection.py) ============================================================================== --- pypy/trunk/pypy/module/_collections/test/test_collection.py (original) +++ pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py Thu Mar 18 04:34:06 2010 @@ -3,10 +3,10 @@ class AppTestIdentityDict: def setup_class(cls): - cls.space = gettestobjspace(usemodules=['_collections']) + cls.space = gettestobjspace(usemodules=['__pypy__']) def test_numbers(self): - from _collections import identity_dict + from __pypy__ import identity_dict d = identity_dict() d[0] = 1 d[0.0] = 2 @@ -18,7 +18,7 @@ assert not d def test_get(self): - from _collections import identity_dict + from __pypy__ import identity_dict d = identity_dict() d[None] = 1 @@ -28,7 +28,7 @@ assert d.get(1, 42) == 42 def test_unhashable(self): - from _collections import identity_dict + from __pypy__ import identity_dict d = identity_dict() d[[]] = 1 @@ -43,7 +43,7 @@ raises(KeyError, d.__getitem__, []) def test_keys(self): - from _collections import identity_dict + from __pypy__ import identity_dict d = identity_dict() d[[]] = 1 d[[]] = 2 @@ -53,7 +53,7 @@ assert sorted(d.values()) == [1, 2, 3] def test_in(self): - from _collections import identity_dict + from __pypy__ import identity_dict d = identity_dict() d[None] = 1 From arigo at codespeak.net Thu Mar 18 04:34:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 04:34:43 +0100 (CET) Subject: [pypy-svn] r72344 - in pypy/branch/kill-python-h/pypy/translator/c: src test Message-ID: <20100318033443.013A7282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 04:34:42 2010 New Revision: 72344 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_include.h pypy/branch/kill-python-h/pypy/translator/c/src/stack.h pypy/branch/kill-python-h/pypy/translator/c/src/thread.h pypy/branch/kill-python-h/pypy/translator/c/src/thread_pthread.h pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py Log: Tweak the macro usage until we no longer depend on pyconfig.h at all. Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/g_include.h Thu Mar 18 04:34:42 2010 @@ -54,9 +54,6 @@ #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" -# ifdef RPyExc_thread_error -# include "src/ll_thread.h" -# endif #endif #endif Modified: pypy/branch/kill-python-h/pypy/translator/c/src/stack.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/stack.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/stack.h Thu Mar 18 04:34:42 2010 @@ -6,9 +6,11 @@ # define MAX_STACK_SIZE (1 << 19) #endif +#ifdef _WIN32 /* This include must be done in any case to initialise - * the header dependencies early (thread -> winsock2, before windows.h) */ -#include "thread.h" + * the header dependencies early (winsock2, before windows.h) */ +# include +#endif void LL_stack_unwind(void); int LL_stack_too_big_slowpath(void); Modified: pypy/branch/kill-python-h/pypy/translator/c/src/thread.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/thread.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/thread.h Thu Mar 18 04:34:42 2010 @@ -9,20 +9,13 @@ #include "thread_nt.h" #else -#include - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -#endif - -#ifdef _POSIX_THREADS +/* We should check if unistd.h defines _POSIX_THREADS, but sometimes + it is not defined even though the system implements them as an + external library (e.g. gnu pth in pthread emulation). So we just + always go ahead and use them, assuming they are supported on all + platforms for which we care. If not, do some detecting again. +*/ #include "thread_pthread.h" -#endif #endif /* !_WIN32 */ Modified: pypy/branch/kill-python-h/pypy/translator/c/src/thread_pthread.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/thread_pthread.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/thread_pthread.h Thu Mar 18 04:34:42 2010 @@ -1,10 +1,24 @@ /* Posix threads interface (from CPython) */ +/* XXX needs to detect HAVE_BROKEN_POSIX_SEMAPHORES properly; currently + it is set only if _POSIX_SEMAPHORES == -1. Seems to be only for + SunOS/5.8 and AIX/5. +*/ + +#include /* for the _POSIX_xxx and _POSIX_THREAD_xxx defines */ +#include #include +#include #include #include +/* The following is hopefully equivalent to what CPython does + (which is trying to compile a snippet of code using it) */ +#ifdef PTHREAD_SCOPE_SYSTEM +# define PTHREAD_SYSTEM_SCHED_SUPPORTED +#endif + /* The POSIX spec says that implementations supporting the sem_* family of functions must indicate this by defining _POSIX_SEMAPHORES. */ @@ -114,11 +128,11 @@ volatile pthread_t threadid; /* Jump through some hoops for Alpha OSF/1 */ threadid = pthread_self(); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (long) threadid; -#else - return (long) *(long *) &threadid; -#endif + + if (sizeof(pthread_t) <= sizeof(long)) + return (long) threadid; + else + return (long) *(long *) &threadid; } static long _pypythread_stacksize = 0; @@ -171,11 +185,10 @@ pthread_detach(th); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (long) th; -#else - return (long) *(long *) &th; -#endif + if (sizeof(pthread_t) <= sizeof(long)) + return (long) th; + else + return (long) *(long *) &th; } long RPyThreadGetStackSize(void) Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py Thu Mar 18 04:34:42 2010 @@ -674,7 +674,10 @@ def entry_point(argv): os.write(1, "hello world\n") error = ll_thread.set_stacksize(int(argv[1])) - assert error == 0 + if error != 0: + os.write(2, "set_stacksize(%d) returned %d\n" % ( + int(argv[1]), error)) + raise AssertionError # malloc a bit s1 = State(); s2 = State(); s3 = State() s1.x = 0x11111111; s2.x = 0x22222222; s3.x = 0x33333333 From arigo at codespeak.net Thu Mar 18 04:39:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 04:39:27 +0100 (CET) Subject: [pypy-svn] r72345 - pypy/branch/kill-python-h/pypy/translator/c/test Message-ID: <20100318033927.1F02E282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 04:39:25 2010 New Revision: 72345 Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_dlltool.py Log: "dlltool" is on my list of stuff to either care about or just kill. Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_dlltool.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/test/test_dlltool.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/test/test_dlltool.py Thu Mar 18 04:39:25 2010 @@ -2,6 +2,7 @@ from pypy.translator.c.dlltool import DLLDef from ctypes import CDLL import py +py.test.skip("fix this if needed") class TestDLLTool(object): def test_basic(self): From arigo at codespeak.net Thu Mar 18 04:53:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 04:53:02 +0100 (CET) Subject: [pypy-svn] r72346 - pypy/branch/kill-python-h/pypy/module/thread/test Message-ID: <20100318035302.7D19B282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 04:53:01 2010 New Revision: 72346 Modified: pypy/branch/kill-python-h/pypy/module/thread/test/test_import_lock.py Log: Fix a test partially. Add an XXX about the part that I did not fix. Modified: pypy/branch/kill-python-h/pypy/module/thread/test/test_import_lock.py ============================================================================== --- pypy/branch/kill-python-h/pypy/module/thread/test/test_import_lock.py (original) +++ pypy/branch/kill-python-h/pypy/module/thread/test/test_import_lock.py Thu Mar 18 04:53:01 2010 @@ -10,17 +10,19 @@ cls.w_tmpdir = cls.space.wrap(tmpdir) def test_import_lock(self): + # XXX XXX XXX this test fails if run together with all other tests + # of this directory, but not when run alone import thread, imp assert not imp.lock_held() done = [] - def f(): + def f(i): print '[ENTER %d]' % i from imghdr import testall print '[LEAVE %d]' % i done.append(1) for i in range(5): print '[RUN %d]' % i - thread.start_new_thread(f, ()) + thread.start_new_thread(f, (i,)) self.waitfor(lambda: len(done) == 5) assert len(done) == 5 From xoraxax at codespeak.net Thu Mar 18 05:05:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 05:05:13 +0100 (CET) Subject: [pypy-svn] r72347 - in pypy/trunk/pypy/lib: . test2 Message-ID: <20100318040513.61CEA282BDE@codespeak.net> Author: xoraxax Date: Thu Mar 18 05:05:11 2010 New Revision: 72347 Added: pypy/trunk/pypy/lib/identity_dict.py pypy/trunk/pypy/lib/test2/test_identitydict.py - copied, changed from r72343, pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py Log: Add identity_dict to pypy/lib. Added: pypy/trunk/pypy/lib/identity_dict.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/lib/identity_dict.py Thu Mar 18 05:05:11 2010 @@ -0,0 +1,56 @@ +try: + from __pypy__ import identity_dict as idict +except ImportError: + idict = None + +from UserDict import DictMixin + + +class IdentityDictPurePython(object, DictMixin): + def __init__(self): + self._dict = {} + self._keys = {} # id(obj) -> obj + + def __getitem__(self, arg): + return self._dict[id(arg)] + + def __setitem__(self, arg, val): + self._keys[id(arg)] = arg + self._dict[id(arg)] = val + + def __delitem__(self, arg): + del self._keys[id(arg)] + del self._dict[id(arg)] + + def keys(self): + return self._keys.values() + + def __contains__(self, arg): + return id(arg) in self._dict + + +class IdentityDictPyPy(object, DictMixin): + def __init__(self): + self._dict = idict() + + def __getitem__(self, arg): + return self._dict[arg] + + def __setitem__(self, arg, val): + self._dict[arg] = val + + def __delitem__(self, arg): + del self._dict[arg] + + def keys(self): + return self._dict.keys() + + def __contains__(self, arg): + return arg in self._dict + + +if idict is None: + identity_dict = IdentityDictPurePython +else: + identity_dict = IdentityDictPyPy + Copied: pypy/trunk/pypy/lib/test2/test_identitydict.py (from r72343, pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py) ============================================================================== --- pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py (original) +++ pypy/trunk/pypy/lib/test2/test_identitydict.py Thu Mar 18 05:05:11 2010 @@ -1,13 +1,11 @@ import py -from pypy.conftest import gettestobjspace +from pypy.lib.identity_dict import identity_dict, IdentityDictPurePython -class AppTestIdentityDict: - def setup_class(cls): - cls.space = gettestobjspace(usemodules=['__pypy__']) +class TestIdentityDictNative: + identity_dict = identity_dict def test_numbers(self): - from __pypy__ import identity_dict - d = identity_dict() + d = self.identity_dict() d[0] = 1 d[0.0] = 2 d[long(0)] = 3 @@ -18,8 +16,7 @@ assert not d def test_get(self): - from __pypy__ import identity_dict - d = identity_dict() + d = self.identity_dict() d[None] = 1 assert d.get(None, 42) == 1 @@ -28,9 +25,7 @@ assert d.get(1, 42) == 42 def test_unhashable(self): - from __pypy__ import identity_dict - - d = identity_dict() + d = self.identity_dict() d[[]] = 1 d[[]] = 2 a = [] @@ -43,8 +38,7 @@ raises(KeyError, d.__getitem__, []) def test_keys(self): - from __pypy__ import identity_dict - d = identity_dict() + d = self.identity_dict() d[[]] = 1 d[[]] = 2 d[[]] = 3 @@ -53,9 +47,12 @@ assert sorted(d.values()) == [1, 2, 3] def test_in(self): - from __pypy__ import identity_dict - d = identity_dict() + d = self.identity_dict() d[None] = 1 assert None in d assert [] not in d + + +class TestIdentityDictPurePython(TestIdentityDictNative): + identity_dict = IdentityDictPurePython From xoraxax at codespeak.net Thu Mar 18 05:33:55 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 05:33:55 +0100 (CET) Subject: [pypy-svn] r72348 - in pypy/trunk/pypy: annotation lib objspace/flow rpython rpython/lltypesystem rpython/memory rpython/ootypesystem tool/algo translator translator/c translator/oosupport translator/tool Message-ID: <20100318043355.BB35A282BDE@codespeak.net> Author: xoraxax Date: Thu Mar 18 05:33:53 2010 New Revision: 72348 Modified: pypy/trunk/pypy/annotation/bookkeeper.py pypy/trunk/pypy/annotation/model.py pypy/trunk/pypy/lib/_sre.py pypy/trunk/pypy/objspace/flow/model.py pypy/trunk/pypy/rpython/lltypesystem/lltype.py pypy/trunk/pypy/rpython/lltypesystem/rclass.py pypy/trunk/pypy/rpython/memory/gctypelayout.py pypy/trunk/pypy/rpython/ootypesystem/rclass.py pypy/trunk/pypy/rpython/rclass.py pypy/trunk/pypy/tool/algo/graphlib.py pypy/trunk/pypy/translator/c/database.py pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/geninterplevel.py pypy/trunk/pypy/translator/oosupport/function.py pypy/trunk/pypy/translator/tool/lltracker.py Log: Use the identity_dict everywhere in the pypy code where grep found a match for [id(. Modified: pypy/trunk/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/trunk/pypy/annotation/bookkeeper.py (original) +++ pypy/trunk/pypy/annotation/bookkeeper.py Thu Mar 18 05:33:53 2010 @@ -22,6 +22,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.ootypesystem import ootype from pypy.rpython import extregistry +from pypy.lib.identity_dict import identity_dict class Stats: @@ -174,7 +175,7 @@ self.stats = Stats(self) # used in SomeObject.__new__ for keeping debugging info - self._someobject_coming_from = {} + self._someobject_coming_from = identity_dict() delayed_imports() Modified: pypy/trunk/pypy/annotation/model.py ============================================================================== --- pypy/trunk/pypy/annotation/model.py (original) +++ pypy/trunk/pypy/annotation/model.py Thu Mar 18 05:33:53 2010 @@ -127,26 +127,26 @@ except AttributeError: pass else: - bookkeeper._someobject_coming_from[id(self)] = position_key, None + bookkeeper._someobject_coming_from[self] = position_key, None return self def origin(self): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return None - return bookkeeper._someobject_coming_from.get(id(self), (None, None))[0] + return bookkeeper._someobject_coming_from.get(self, (None, None))[0] origin = property(origin) def caused_by_merge(self): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return None - return bookkeeper._someobject_coming_from.get(id(self), (None, None))[1] + return bookkeeper._someobject_coming_from.get(self, (None, None))[1] def set_caused_by_merge(self, nvalue): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return - bookkeeper._someobject_coming_from[id(self)] = self.origin, nvalue + bookkeeper._someobject_coming_from[self] = self.origin, nvalue caused_by_merge = property(caused_by_merge, set_caused_by_merge) del set_caused_by_merge Modified: pypy/trunk/pypy/lib/_sre.py ============================================================================== --- pypy/trunk/pypy/lib/_sre.py (original) +++ pypy/trunk/pypy/lib/_sre.py Thu Mar 18 05:33:53 2010 @@ -18,6 +18,9 @@ MAGIC = 20030419 import array, operator + +from identity_dict import identity_dict + from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT from sre_constants import SRE_INFO_PREFIX, SRE_INFO_LITERAL from sre_constants import SRE_FLAG_UNICODE, SRE_FLAG_LOCALE @@ -573,7 +576,7 @@ class _OpcodeDispatcher(_Dispatcher): def __init__(self): - self.executing_contexts = {} + self.executing_contexts = identity_dict() self.at_dispatcher = _AtcodeDispatcher() self.ch_dispatcher = _ChcodeDispatcher() self.set_dispatcher = _CharsetDispatcher() @@ -593,9 +596,9 @@ def dispatch(self, opcode, context): """Dispatches a context on a given opcode. Returns True if the context is done matching, False if it must be resumed when next encountered.""" - if self.executing_contexts.has_key(id(context)): - generator = self.executing_contexts[id(context)] - del self.executing_contexts[id(context)] + if self.executing_contexts.has_key(context): + generator = self.executing_contexts[context] + del self.executing_contexts[context] has_finished = generator.next() else: method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) @@ -604,7 +607,7 @@ generator = has_finished has_finished = generator.next() if not has_finished: - self.executing_contexts[id(context)] = generator + self.executing_contexts[context] = generator return has_finished def op_success(self, ctx): Modified: pypy/trunk/pypy/objspace/flow/model.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/model.py (original) +++ pypy/trunk/pypy/objspace/flow/model.py Thu Mar 18 05:33:53 2010 @@ -7,6 +7,7 @@ from pypy.tool.uid import uid, Hashable from pypy.tool.descriptor import roproperty from pypy.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func +from pypy.lib.identity_dict import identity_dict """ memory size before and after introduction of __slots__ @@ -379,15 +380,16 @@ def traverse(visit, functiongraph): block = functiongraph.startblock visit(block) - seen = {id(block): True} + seen = identity_dict() + seen[block] = True stack = list(block.exits[::-1]) while stack: link = stack.pop() visit(link) block = link.target - if id(block) not in seen: + if block not in seen: visit(block) - seen[id(block)] = True + seen[block] = True stack += block.exits[::-1] Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lltype.py Thu Mar 18 05:33:53 2010 @@ -1938,7 +1938,7 @@ memo = {} if id(v) in memo: return - memo[id(v)] = True + memo[id(v)] = True # could use an identity dict if there wasnt the parameter if t is None: t = typeOf(v) yield t, v Modified: pypy/trunk/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rclass.py Thu Mar 18 05:33:53 2010 @@ -21,6 +21,7 @@ from pypy.annotation import model as annmodel from pypy.rlib.rarithmetic import intmask from pypy.rlib import objectmodel +from pypy.lib.identity_dict import identity_dict # # There is one "vtable" per user class, with the following structure: @@ -310,7 +311,7 @@ ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() - self.prebuiltinstances = {} # { id(x): (x, _ptr) } + self.prebuiltinstances = identity_dict() self.lowleveltype = Ptr(self.object_type) self.gcflavor = gcflavor Modified: pypy/trunk/pypy/rpython/memory/gctypelayout.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctypelayout.py (original) +++ pypy/trunk/pypy/rpython/memory/gctypelayout.py Thu Mar 18 05:33:53 2010 @@ -3,6 +3,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import ll_assert +from pypy.lib.identity_dict import identity_dict class GCData(object): @@ -182,7 +183,7 @@ self.lltype2vtable = lltype2vtable self.make_type_info_group() self.id_of_type = {} # {LLTYPE: type_id} - self.seen_roots = {} + self.seen_roots = identity_dict() # the following are lists of addresses of gc pointers living inside the # prebuilt structures. It should list all the locations that could # possibly point to a GC heap object. @@ -309,9 +310,9 @@ def consider_constant(self, TYPE, value, gc): if value is not lltype.top_container(value): return - if id(value) in self.seen_roots: + if value in self.seen_roots: return - self.seen_roots[id(value)] = True + self.seen_roots[value] = True if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)): typeid = self.get_type_id(TYPE) Modified: pypy/trunk/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/ootypesystem/rclass.py Thu Mar 18 05:33:53 2010 @@ -10,6 +10,7 @@ from pypy.rpython.exceptiondata import standardexceptions from pypy.tool.pairtype import pairtype from pypy.tool.sourcetools import func_with_new_name +from pypy.lib.identity_dict import identity_dict OBJECT = ootype.ROOT META = ootype.Instance("Meta", ootype.ROOT, @@ -184,7 +185,7 @@ hints = {} hints = self._check_for_immutable_hints(hints) self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints = hints) - self.prebuiltinstances = {} # { id(x): (x, _ptr) } + self.prebuiltinstances = identity_dict() self.object_type = self.lowleveltype self.gcflavor = gcflavor Modified: pypy/trunk/pypy/rpython/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/rclass.py (original) +++ pypy/trunk/pypy/rpython/rclass.py Thu Mar 18 05:33:53 2010 @@ -223,11 +223,11 @@ def convert_const_exact(self, value): try: - return self.prebuiltinstances[id(value)][1] + return self.prebuiltinstances[value][1] except KeyError: self.setup() result = self.create_instance() - self.prebuiltinstances[id(value)] = value, result + self.prebuiltinstances[value] = value, result self.initialize_prebuilt_instance(value, self.classdef, result) return result Modified: pypy/trunk/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/trunk/pypy/tool/algo/graphlib.py (original) +++ pypy/trunk/pypy/tool/algo/graphlib.py Thu Mar 18 05:33:53 2010 @@ -6,6 +6,8 @@ 'edges' is a dict mapping vertices to a list of edges with its source. Note that we can usually use 'edges' as the set of 'vertices' too. """ +from pypy.lib.identity_dict import identity_dict + class Edge: def __init__(self, source, target): @@ -199,12 +201,12 @@ roots_finished.add(root) continue #print 'from root %r: %d cycles' % (root, len(cycles)) - allcycles = {} + allcycles = identity_dict() edge2cycles = {} for cycle in cycles: - allcycles[id(cycle)] = cycle + allcycles[cycle] = cycle for edge in cycle: - edge2cycles.setdefault(edge, []).append(id(cycle)) + edge2cycles.setdefault(edge, []).append(cycle) edge_weights = {} for edge, cycle in edge2cycles.iteritems(): edge_weights[edge] = len(cycle) @@ -221,8 +223,8 @@ yield max_edge progress = True # unregister all cycles that have just been broken - for broken_cycle_id in edge2cycles[max_edge]: - broken_cycle = allcycles.pop(broken_cycle_id, ()) + for broken_cycle in edge2cycles[max_edge]: + broken_cycle = allcycles.pop(broken_cycle, ()) for edge in broken_cycle: edge_weights[edge] -= 1 Modified: pypy/trunk/pypy/translator/c/database.py ============================================================================== --- pypy/trunk/pypy/translator/c/database.py (original) +++ pypy/trunk/pypy/translator/c/database.py Thu Mar 18 05:33:53 2010 @@ -16,6 +16,8 @@ from pypy.translator.c.extfunc import do_the_getting from pypy import conftest from pypy.translator.c import gc +from pypy.lib.identity_dict import identity_dict + class NoCorrespondingNode(Exception): pass @@ -42,7 +44,7 @@ self.pendingsetupnodes = [] self.containernodes = {} self.containerlist = [] - self.delayedfunctionnames = {} + self.delayedfunctionnames = identity_dict() self.delayedfunctionptrs = [] self.completedcontainers = 0 self.containerstats = {} @@ -191,11 +193,11 @@ if len(name) == n: raise if isinstance(lltype.typeOf(obj).TO, lltype.FuncType): - if id(obj) in self.delayedfunctionnames: - return self.delayedfunctionnames[id(obj)][0] + if obj in self.delayedfunctionnames: + return self.delayedfunctionnames[obj][0] funcname = name[n:] funcname = self.namespace.uniquename('g_'+funcname) - self.delayedfunctionnames[id(obj)] = funcname, obj + self.delayedfunctionnames[obj] = funcname, obj else: funcname = None # can't use the name of a # delayed non-function ptr @@ -204,10 +206,10 @@ # /hack hack hack else: # hack hack hack - if id(obj) in self.delayedfunctionnames: + if obj in self.delayedfunctionnames: # this used to be a delayed function, # make sure we use the same name - forcename = self.delayedfunctionnames[id(obj)][0] + forcename = self.delayedfunctionnames[obj][0] node = self.getcontainernode(container, forcename=forcename) assert node.ptrname == forcename Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Thu Mar 18 05:33:53 2010 @@ -13,6 +13,8 @@ from pypy.rpython.lltypesystem.llmemory import Address from pypy.translator.backendopt.ssa import SSI_to_SSA from pypy.translator.backendopt.innerloop import find_inner_loops +from pypy.lib.identity_dict import identity_dict + PyObjPtr = Ptr(PyObject) LOCALVAR = 'l_%s' @@ -95,11 +97,11 @@ mix.append(cleanupop.result) uniquemix = [] - seen = {} + seen = identity_dict() for v in mix: - if id(v) not in seen: + if v not in seen: uniquemix.append(v) - seen[id(v)] = True + seen[v] = True self.vars = uniquemix def name(self, cname): #virtual @@ -122,11 +124,11 @@ for block in self.graph.iterblocks(): self.blocknum[block] = len(self.blocknum) db = self.db - lltypes = {} + lltypes = identity_dict() for v in self.vars: T = getattr(v, 'concretetype', PyObjPtr) typename = db.gettype(T) - lltypes[id(v)] = T, typename + lltypes[v] = T, typename self.lltypes = lltypes self.innerloops = {} # maps the loop's header block to a Loop() for loop in find_inner_loops(self.graph, Bool): @@ -161,11 +163,11 @@ yield llvalue def lltypemap(self, v): - T, typename = self.lltypes[id(v)] + T, typename = self.lltypes[v] return T def lltypename(self, v): - T, typename = self.lltypes[id(v)] + T, typename = self.lltypes[v] return typename def expr(self, v, special_case_void=True): @@ -298,7 +300,7 @@ is_alive = {} assignments = [] for a1, a2 in zip(link.args, link.target.inputargs): - a2type, a2typename = self.lltypes[id(a2)] + a2type, a2typename = self.lltypes[a2] if a2type is Void: continue src = self.expr(a1) Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Thu Mar 18 05:33:53 2010 @@ -62,7 +62,7 @@ from pypy.translator.gensupp import ordered_blocks, UniqueList, builtin_base, \ uniquemodulename, C_IDENTIFIER, NameManager - +from pypy.lib.identity_dict import identity_dict import pypy # __path__ import py.path @@ -194,10 +194,11 @@ def __repr__(self): return '<%s>' % self.__name__ - self.builtin_ids = dict( [ - (id(value), bltinstub(key)) + self.builtin_ids = identity_dict() + self.builtin_ids.update(dict( [ + (value, bltinstub(key)) for key, value in __builtin__.__dict__.items() - if callable(value) and type(value) not in [types.ClassType, type] ] ) + if callable(value) and type(value) not in [types.ClassType, type] ] )) self.space = FlowObjSpace() # for introspection @@ -391,8 +392,8 @@ name = self.nameof_instance(obj) else: # shortcutting references to __builtin__ - if id(obj) in self.builtin_ids: - func = self.builtin_ids[id(obj)] + if obj in self.builtin_ids: + func = self.builtin_ids[obj] #name = self.get_nameof_builtin_func(func) # the above is quicker in principle, but pulls more # stuff in, so it is slower right now. @@ -705,8 +706,8 @@ return self._space_arities def try_space_shortcut_for_builtin(self, v, nargs, args): - if isinstance(v, Constant) and id(v.value) in self.builtin_ids: - name = self.builtin_ids[id(v.value)].__name__ + if isinstance(v, Constant) and v.value in self.builtin_ids: + name = self.builtin_ids[v.value].__name__ if hasattr(self.space, name): if self.space_arities().get(name, -1) == nargs: if name != 'isinstance': @@ -726,8 +727,8 @@ def nameof_builtin_function(self, func): # builtin function - if id(func) in self.builtin_ids: - func = self.builtin_ids[id(func)] + if func in self.builtin_ids: + func = self.builtin_ids[func] return "(space.builtin.get(space.str_w(%s)))" % self.nameof(func.__name__) # where does it come from? Python2.2 doesn't have func.__module__ for modname, module in sys.modules.items(): Modified: pypy/trunk/pypy/translator/oosupport/function.py ============================================================================== --- pypy/trunk/pypy/translator/oosupport/function.py (original) +++ pypy/trunk/pypy/translator/oosupport/function.py Thu Mar 18 05:33:53 2010 @@ -7,6 +7,8 @@ from pypy.rpython.ootypesystem import ootype from pypy.translator.oosupport.treebuilder import SubOperation from pypy.translator.oosupport.metavm import InstructionList, StoreResult +from pypy.lib.identity_dict import identity_dict + def render_sub_op(sub_op, db, generator): op = sub_op.op @@ -424,12 +426,12 @@ args[name] = True locals = [] - seen = {} + seen = identity_dict() for v in mix: is_var = isinstance(v, flowmodel.Variable) - if id(v) not in seen and is_var and v.name not in args and v.concretetype is not ootype.Void: + if v not in seen and is_var and v.name not in args and v.concretetype is not ootype.Void: locals.append(self.cts.llvar_to_cts(v)) - seen[id(v)] = True + seen[v] = True self.locals = locals Modified: pypy/trunk/pypy/translator/tool/lltracker.py ============================================================================== --- pypy/trunk/pypy/translator/tool/lltracker.py (original) +++ pypy/trunk/pypy/translator/tool/lltracker.py Thu Mar 18 05:33:53 2010 @@ -8,6 +8,7 @@ from pypy.rpython.memory.gcheader import header2obj from pypy.translator.tool.reftracker import BaseRefTrackerPage, MARKER from pypy.tool.uid import uid +from pypy.lib.identity_dict import identity_dict class LLRefTrackerPage(BaseRefTrackerPage): @@ -121,7 +122,7 @@ """Invoke a dot+pygame object reference tracker.""" lst = [MARKER] size_gc_header = None - seen = {} + seen = identity_dict() for ll_object in ll_objects: if isinstance(ll_object, llmemory.GCHeaderOffset): size_gc_header = ll_object @@ -132,9 +133,9 @@ # ll_object = ptr._obj # else: # ll_object = None - if ll_object is not None and id(ll_object) not in seen: + if ll_object is not None and ll_object not in seen: lst.append(ll_object) - seen[id(ll_object)] = ll_object + seen[ll_object] = ll_object page = LLRefTrackerPage(lst, size_gc_header) # auto-expand one level, for now auto_expand = 1 @@ -142,9 +143,9 @@ page = page.content() for ll_object in lst[1:]: for name, value in page.enum_content(ll_object): - if not isinstance(value, str) and id(value) not in seen: + if not isinstance(value, str) and value not in seen: lst.append(value) - seen[id(value)] = value + seen[value] = value page = page.newpage(lst) page.display() From xoraxax at codespeak.net Thu Mar 18 05:36:24 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 05:36:24 +0100 (CET) Subject: [pypy-svn] r72349 - pypy/trunk/pypy/lib Message-ID: <20100318043624.6F523282BDE@codespeak.net> Author: xoraxax Date: Thu Mar 18 05:36:23 2010 New Revision: 72349 Modified: pypy/trunk/pypy/lib/identity_dict.py Log: Use slots for identity_dict. Modified: pypy/trunk/pypy/lib/identity_dict.py ============================================================================== --- pypy/trunk/pypy/lib/identity_dict.py (original) +++ pypy/trunk/pypy/lib/identity_dict.py Thu Mar 18 05:36:23 2010 @@ -7,6 +7,8 @@ class IdentityDictPurePython(object, DictMixin): + __slots__ = "_dict _keys".split() + def __init__(self): self._dict = {} self._keys = {} # id(obj) -> obj @@ -30,6 +32,8 @@ class IdentityDictPyPy(object, DictMixin): + __slots__ = ["_dict"] + def __init__(self): self._dict = idict() From xoraxax at codespeak.net Thu Mar 18 07:09:56 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 07:09:56 +0100 (CET) Subject: [pypy-svn] r72350 - in pypy/trunk/pypy/module/__pypy__: . test Message-ID: <20100318060956.4B043282BDE@codespeak.net> Author: xoraxax Date: Thu Mar 18 07:09:54 2010 New Revision: 72350 Modified: pypy/trunk/pypy/module/__pypy__/interp_identitydict.py pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py Log: Add delitem to identity dict. Modified: pypy/trunk/pypy/module/__pypy__/interp_identitydict.py ============================================================================== --- pypy/trunk/pypy/module/__pypy__/interp_identitydict.py (original) +++ pypy/trunk/pypy/module/__pypy__/interp_identitydict.py Thu Mar 18 07:09:54 2010 @@ -34,6 +34,13 @@ except KeyError: raise OperationError(space.w_KeyError, w_key) + @unwrap_spec('self', ObjSpace, W_Root) + def descr_delitem(self, space, w_key): + try: + del self.dict[w_key] + except KeyError: + raise OperationError(space.w_KeyError, w_key) + @unwrap_spec('self', ObjSpace, W_Root, W_Root) def get(self, space, w_key, w_default=None): return self.dict.get(w_key, w_default) @@ -61,6 +68,7 @@ __contains__ = interp2app(W_IdentityDict.descr_contains), __setitem__ = interp2app(W_IdentityDict.descr_setitem), __getitem__ = interp2app(W_IdentityDict.descr_getitem), + __delitem__ = interp2app(W_IdentityDict.descr_delitem), get = interp2app(W_IdentityDict.get), keys = interp2app(W_IdentityDict.keys), values = interp2app(W_IdentityDict.values), Modified: pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py ============================================================================== --- pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py (original) +++ pypy/trunk/pypy/module/__pypy__/test/test_identitydict.py Thu Mar 18 07:09:54 2010 @@ -14,6 +14,7 @@ assert d assert len(d) == 3 + del d[0] d.clear() assert not d From arigo at codespeak.net Thu Mar 18 10:54:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 10:54:33 +0100 (CET) Subject: [pypy-svn] r72357 - pypy/branch/kill-python-h/pypy/translator/c/src Message-ID: <20100318095433.BB881282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 10:54:32 2010 New Revision: 72357 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/stack.h Log: It is necessary after all to include thread.h here. Modified: pypy/branch/kill-python-h/pypy/translator/c/src/stack.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/stack.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/stack.h Thu Mar 18 10:54:32 2010 @@ -6,11 +6,10 @@ # define MAX_STACK_SIZE (1 << 19) #endif -#ifdef _WIN32 /* This include must be done in any case to initialise - * the header dependencies early (winsock2, before windows.h) */ -# include -#endif + * the header dependencies early (winsock2, before windows.h). + * It is needed to have RPyThreadStaticTLS, too. */ +#include "thread.h" void LL_stack_unwind(void); int LL_stack_too_big_slowpath(void); From cfbolz at codespeak.net Thu Mar 18 10:59:02 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Mar 2010 10:59:02 +0100 (CET) Subject: [pypy-svn] r72358 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100318095902.DC184282BDE@codespeak.net> Author: cfbolz Date: Thu Mar 18 10:59:01 2010 New Revision: 72358 Modified: pypy/extradoc/talk/oopsla2010/related_work.txt Log: smalltalks frames comment Modified: pypy/extradoc/talk/oopsla2010/related_work.txt ============================================================================== --- pypy/extradoc/talk/oopsla2010/related_work.txt (original) +++ pypy/extradoc/talk/oopsla2010/related_work.txt Thu Mar 18 10:59:01 2010 @@ -9,7 +9,9 @@ Smalltalk ========= -I'm not aware of frame introspection capabilities in smalltalk +Smalltalk has both frame introspection (everything is an object) and optimizes +its frame objects heavily in some implementations: +http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.6597 Psyco ===== From arigo at codespeak.net Thu Mar 18 11:07:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 11:07:35 +0100 (CET) Subject: [pypy-svn] r72359 - pypy/branch/kill-python-h/pypy/rpython/test Message-ID: <20100318100735.D55CC282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 11:07:34 2010 New Revision: 72359 Modified: pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py Log: A failing test. Modified: pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py Thu Mar 18 11:07:34 2010 @@ -1,3 +1,4 @@ +import py import sys, operator from pypy.translator.translator import TranslationContext from pypy.annotation import model as annmodel @@ -105,6 +106,17 @@ res = self.ll_to_string(res) assert res == '-' + oct(sys.maxint+1).replace('L', '').replace('l', '') + def test_str_of_longlong(self): + py.test.skip("Fails. Do we want to fix it or not? Unclear.") + def f(i): + return str(i) + + res = self.interpret(f, [r_longlong(0)]) + assert self.ll_to_string(res) == '0' + + res = self.interpret(f, [r_longlong(413974738222117)]) + assert self.ll_to_string(res) == '413974738222117' + def test_unsigned(self): bigvalue = sys.maxint + 17 def dummy(i): From arigo at codespeak.net Thu Mar 18 11:11:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 11:11:43 +0100 (CET) Subject: [pypy-svn] r72360 - pypy/branch/kill-python-h/pypy/translator/c/test Message-ID: <20100318101143.031AA282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 11:11:42 2010 New Revision: 72360 Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py Log: This is not really about sparse files, and it's precisely on Windows that it fails. Rewrite the test so it can be unskipped on Windows (and then it fails). Modified: pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/test/test_standalone.py Thu Mar 18 11:11:42 2010 @@ -205,16 +205,13 @@ #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: + if newpos == r4800000000: print "OK" else: print "BAD POS" From arigo at codespeak.net Thu Mar 18 11:17:07 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 11:17:07 +0100 (CET) Subject: [pypy-svn] r72361 - in pypy/branch/kill-python-h/pypy/rpython: lltypesystem test Message-ID: <20100318101707.82FD9282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 11:17:06 2010 New Revision: 72361 Modified: pypy/branch/kill-python-h/pypy/rpython/lltypesystem/ll_str.py pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py Log: Fixed the failing test. Modified: pypy/branch/kill-python-h/pypy/rpython/lltypesystem/ll_str.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/lltypesystem/ll_str.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/lltypesystem/ll_str.py Thu Mar 18 11:17:06 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem.lltype import GcArray, Array, Char, malloc from pypy.rpython.annlowlevel import llstr -from pypy.rlib.rarithmetic import r_uint, formatd +from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, formatd CHAR_ARRAY = GcArray(Char) @@ -8,6 +8,12 @@ return ll_int2dec(i) ll_int_str._pure_function_ = True +def ll_unsigned(i): + if isinstance(i, r_longlong) or isinstance(i, r_ulonglong): + return r_ulonglong(i) + else: + return r_uint(i) + def ll_int2dec(i): from pypy.rpython.lltypesystem.rstr import mallocstr temp = malloc(CHAR_ARRAY, 20) @@ -15,9 +21,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) if i == 0: len = 1 temp[0] = '0' @@ -52,9 +58,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) if i == 0: len = 1 temp[0] = '0' @@ -94,9 +100,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) while i: temp[len] = hex_chars[i & 0x7] i >>= 3 Modified: pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py (original) +++ pypy/branch/kill-python-h/pypy/rpython/test/test_rint.py Thu Mar 18 11:17:06 2010 @@ -107,7 +107,6 @@ assert res == '-' + oct(sys.maxint+1).replace('L', '').replace('l', '') def test_str_of_longlong(self): - py.test.skip("Fails. Do we want to fix it or not? Unclear.") def f(i): return str(i) From arigo at codespeak.net Thu Mar 18 11:48:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 11:48:19 +0100 (CET) Subject: [pypy-svn] r72365 - pypy/branch/kill-python-h/pypy/translator/c/src Message-ID: <20100318104819.B90F0282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 11:48:18 2010 New Revision: 72365 Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h Log: Bah. Modified: pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/branch/kill-python-h/pypy/translator/c/src/g_prerequisite.h Thu Mar 18 11:48:18 2010 @@ -9,6 +9,9 @@ # include "Python.h" #endif +#ifdef _WIN32 +# include /* needed, otherwise _lseeki64 truncates to 32-bits (??) */ +#endif #ifndef AVR #include "thread.h" /* needs to be included early to define the From arigo at codespeak.net Thu Mar 18 12:39:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 12:39:31 +0100 (CET) Subject: [pypy-svn] r72368 - pypy/branch/kill-python-h/py/plugin Message-ID: <20100318113931.84012282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 12:39:30 2010 New Revision: 72368 Modified: pypy/branch/kill-python-h/py/plugin/pytest_resultlog.py Log: Untested. Try to be safe against str(unicode-with-non-standard-chars). Modified: pypy/branch/kill-python-h/py/plugin/pytest_resultlog.py ============================================================================== --- pypy/branch/kill-python-h/py/plugin/pytest_resultlog.py (original) +++ pypy/branch/kill-python-h/py/plugin/pytest_resultlog.py Thu Mar 18 12:39:30 2010 @@ -68,15 +68,15 @@ else: code = report.shortrepr if code == 'x': - longrepr = str(report.longrepr) + longrepr = safestr(report.longrepr) elif code == 'P': longrepr = '' elif report.passed: longrepr = "" elif report.failed: - longrepr = str(report.longrepr) + longrepr = safestr(report.longrepr) elif report.skipped: - longrepr = str(report.longrepr.reprcrash.message) + longrepr = safestr(report.longrepr.reprcrash.message) self.log_outcome(report.item, code, longrepr) def pytest_collectreport(self, report): @@ -86,9 +86,16 @@ else: assert report.skipped code = "S" - longrepr = str(report.longrepr.reprcrash) + longrepr = safestr(report.longrepr.reprcrash) self.log_outcome(report.collector, code, longrepr) def pytest_internalerror(self, excrepr): path = excrepr.reprcrash.path - self.write_log_entry(path, '!', str(excrepr)) + self.write_log_entry(path, '!', safestr(excrepr)) + + +def safestr(x): + if isinstance(x, unicode): + return x.encode('utf-8') + else: + return str(x) From arigo at codespeak.net Thu Mar 18 12:51:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 12:51:47 +0100 (CET) Subject: [pypy-svn] r72369 - pypy/build/bot2/pypybuildbot Message-ID: <20100318115147.29B93282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 12:51:45 2010 New Revision: 72369 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: Comment out uploading of the pypy-c. On codespeak, the current run on Builder pypy-c-jit-linux-x86-32: Build #154 seems to deadlock on that step. Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Mar 18 12:51:45 2010 @@ -112,9 +112,9 @@ # upload nightly build, if we're running jit tests nightly = os.path.expanduser('~/nightly/pypy-c-jit-%(got_revision)s-' + platform) pypy_c_rel = 'build/pypy/translator/goal/pypy-c' - self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, - masterdest=WithProperties(nightly), - workdir='.')) + #self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, + # masterdest=WithProperties(nightly), + # workdir='.')) self.addStep(ShellCmd( description="pypyjit tests", command=["python", "pypy/test_all.py", From xoraxax at codespeak.net Thu Mar 18 14:37:06 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 18 Mar 2010 14:37:06 +0100 (CET) Subject: [pypy-svn] r72372 - in pypy/trunk/pypy: rpython/lltypesystem rpython/lltypesystem/test translator Message-ID: <20100318133706.1E35C282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 18 14:37:04 2010 New Revision: 72372 Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py pypy/trunk/pypy/translator/geninterplevel.py Log: Fix geninterp and use identity_dict in dissect_ll_instance. Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lltype.py Thu Mar 18 14:37:04 2010 @@ -5,6 +5,7 @@ from pypy.rlib.objectmodel import Symbolic from pypy.tool.uid import Hashable from pypy.tool.tls import tlsobject +from pypy.lib.identity_dict import identity_dict from types import NoneType from sys import maxint import struct @@ -1935,10 +1936,10 @@ def dissect_ll_instance(v, t=None, memo=None): if memo is None: - memo = {} - if id(v) in memo: + memo = identity_dict() + if v in memo: return - memo[id(v)] = True # could use an identity dict if there wasnt the parameter + memo[v] = True if t is None: t = typeOf(v) yield t, v Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_lltype.py Thu Mar 18 14:37:04 2010 @@ -1,4 +1,5 @@ from pypy.rpython.lltypesystem.lltype import * +from pypy.lib.identity_dict import identity_dict def isweak(p, T): try: @@ -620,7 +621,7 @@ b_expected = [(Ptr(B), b), (B, b._obj)] assert list(dissect_ll_instance(b)) == b_expected + r_expected - memo = {} + memo = identity_dict() assert list(dissect_ll_instance(r, None, memo)) == r_expected assert list(dissect_ll_instance(b, None, memo)) == b_expected Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Thu Mar 18 14:37:04 2010 @@ -195,10 +195,10 @@ return '<%s>' % self.__name__ self.builtin_ids = identity_dict() - self.builtin_ids.update(dict( [ + self.builtin_ids.update([ (value, bltinstub(key)) for key, value in __builtin__.__dict__.items() - if callable(value) and type(value) not in [types.ClassType, type] ] )) + if callable(value) and type(value) not in [types.ClassType, type] ] ) self.space = FlowObjSpace() # for introspection From arigo at codespeak.net Thu Mar 18 14:42:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 14:42:10 +0100 (CET) Subject: [pypy-svn] r72373 - in pypy/trunk/pypy: annotation rpython rpython/lltypesystem rpython/memory rpython/ootypesystem translator translator/c Message-ID: <20100318134210.7CEBD282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 14:42:08 2010 New Revision: 72373 Modified: pypy/trunk/pypy/annotation/bookkeeper.py pypy/trunk/pypy/annotation/model.py pypy/trunk/pypy/rpython/lltypesystem/rclass.py pypy/trunk/pypy/rpython/memory/gctypelayout.py pypy/trunk/pypy/rpython/ootypesystem/rclass.py pypy/trunk/pypy/rpython/rclass.py pypy/trunk/pypy/translator/c/database.py pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/geninterplevel.py Log: Rename some of the instances attributes that now contain an identity_dict rather than a plain dict. Might be useful in catching unexpected usage of these attributes. Modified: pypy/trunk/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/trunk/pypy/annotation/bookkeeper.py (original) +++ pypy/trunk/pypy/annotation/bookkeeper.py Thu Mar 18 14:42:08 2010 @@ -175,7 +175,7 @@ self.stats = Stats(self) # used in SomeObject.__new__ for keeping debugging info - self._someobject_coming_from = identity_dict() + self._isomeobject_coming_from = identity_dict() delayed_imports() Modified: pypy/trunk/pypy/annotation/model.py ============================================================================== --- pypy/trunk/pypy/annotation/model.py (original) +++ pypy/trunk/pypy/annotation/model.py Thu Mar 18 14:42:08 2010 @@ -127,26 +127,26 @@ except AttributeError: pass else: - bookkeeper._someobject_coming_from[self] = position_key, None + bookkeeper._isomeobject_coming_from[self] = position_key, None return self def origin(self): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return None - return bookkeeper._someobject_coming_from.get(self, (None, None))[0] + return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0] origin = property(origin) def caused_by_merge(self): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return None - return bookkeeper._someobject_coming_from.get(self, (None, None))[1] + return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1] def set_caused_by_merge(self, nvalue): bookkeeper = pypy.annotation.bookkeeper.getbookkeeper() if bookkeeper is None: return - bookkeeper._someobject_coming_from[self] = self.origin, nvalue + bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue caused_by_merge = property(caused_by_merge, set_caused_by_merge) del set_caused_by_merge Modified: pypy/trunk/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rclass.py Thu Mar 18 14:42:08 2010 @@ -311,7 +311,7 @@ ForwardRef = lltype.FORWARDREF_BY_FLAVOR[LLFLAVOR[gcflavor]] self.object_type = ForwardRef() - self.prebuiltinstances = identity_dict() + self.iprebuiltinstances = identity_dict() self.lowleveltype = Ptr(self.object_type) self.gcflavor = gcflavor Modified: pypy/trunk/pypy/rpython/memory/gctypelayout.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctypelayout.py (original) +++ pypy/trunk/pypy/rpython/memory/gctypelayout.py Thu Mar 18 14:42:08 2010 @@ -183,7 +183,7 @@ self.lltype2vtable = lltype2vtable self.make_type_info_group() self.id_of_type = {} # {LLTYPE: type_id} - self.seen_roots = identity_dict() + self.iseen_roots = identity_dict() # the following are lists of addresses of gc pointers living inside the # prebuilt structures. It should list all the locations that could # possibly point to a GC heap object. @@ -310,9 +310,9 @@ def consider_constant(self, TYPE, value, gc): if value is not lltype.top_container(value): return - if value in self.seen_roots: + if value in self.iseen_roots: return - self.seen_roots[value] = True + self.iseen_roots[value] = True if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)): typeid = self.get_type_id(TYPE) Modified: pypy/trunk/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/trunk/pypy/rpython/ootypesystem/rclass.py Thu Mar 18 14:42:08 2010 @@ -185,7 +185,7 @@ hints = {} hints = self._check_for_immutable_hints(hints) self.lowleveltype = ootype.Instance(classdef.name, b, {}, {}, _hints = hints) - self.prebuiltinstances = identity_dict() + self.iprebuiltinstances = identity_dict() self.object_type = self.lowleveltype self.gcflavor = gcflavor Modified: pypy/trunk/pypy/rpython/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/rclass.py (original) +++ pypy/trunk/pypy/rpython/rclass.py Thu Mar 18 14:42:08 2010 @@ -223,11 +223,11 @@ def convert_const_exact(self, value): try: - return self.prebuiltinstances[value][1] + return self.iprebuiltinstances[value][1] except KeyError: self.setup() result = self.create_instance() - self.prebuiltinstances[value] = value, result + self.iprebuiltinstances[value] = value, result self.initialize_prebuilt_instance(value, self.classdef, result) return result Modified: pypy/trunk/pypy/translator/c/database.py ============================================================================== --- pypy/trunk/pypy/translator/c/database.py (original) +++ pypy/trunk/pypy/translator/c/database.py Thu Mar 18 14:42:08 2010 @@ -44,7 +44,7 @@ self.pendingsetupnodes = [] self.containernodes = {} self.containerlist = [] - self.delayedfunctionnames = identity_dict() + self.idelayedfunctionnames = identity_dict() self.delayedfunctionptrs = [] self.completedcontainers = 0 self.containerstats = {} @@ -193,11 +193,11 @@ if len(name) == n: raise if isinstance(lltype.typeOf(obj).TO, lltype.FuncType): - if obj in self.delayedfunctionnames: - return self.delayedfunctionnames[obj][0] + if obj in self.idelayedfunctionnames: + return self.idelayedfunctionnames[obj][0] funcname = name[n:] funcname = self.namespace.uniquename('g_'+funcname) - self.delayedfunctionnames[obj] = funcname, obj + self.idelayedfunctionnames[obj] = funcname, obj else: funcname = None # can't use the name of a # delayed non-function ptr @@ -206,10 +206,10 @@ # /hack hack hack else: # hack hack hack - if obj in self.delayedfunctionnames: + if obj in self.idelayedfunctionnames: # this used to be a delayed function, # make sure we use the same name - forcename = self.delayedfunctionnames[obj][0] + forcename = self.idelayedfunctionnames[obj][0] node = self.getcontainernode(container, forcename=forcename) assert node.ptrname == forcename Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Thu Mar 18 14:42:08 2010 @@ -65,7 +65,7 @@ continue db.gettype(T) # force the type to be considered by the database - self.lltypes = None + self.illtypes = None def collect_var_and_types(self): # @@ -129,7 +129,7 @@ T = getattr(v, 'concretetype', PyObjPtr) typename = db.gettype(T) lltypes[v] = T, typename - self.lltypes = lltypes + self.illtypes = lltypes self.innerloops = {} # maps the loop's header block to a Loop() for loop in find_inner_loops(self.graph, Bool): self.innerloops[loop.headblock] = loop @@ -139,7 +139,7 @@ def implementation_end(self): self.all_cached_consts = list(self.allconstantvalues()) - self.lltypes = None + self.illtypes = None self.vars = None self.blocknum = None self.innerloops = None @@ -163,11 +163,11 @@ yield llvalue def lltypemap(self, v): - T, typename = self.lltypes[v] + T, typename = self.illtypes[v] return T def lltypename(self, v): - T, typename = self.lltypes[v] + T, typename = self.illtypes[v] return typename def expr(self, v, special_case_void=True): @@ -300,7 +300,7 @@ is_alive = {} assignments = [] for a1, a2 in zip(link.args, link.target.inputargs): - a2type, a2typename = self.lltypes[a2] + a2type, a2typename = self.illtypes[a2] if a2type is Void: continue src = self.expr(a1) Modified: pypy/trunk/pypy/translator/geninterplevel.py ============================================================================== --- pypy/trunk/pypy/translator/geninterplevel.py (original) +++ pypy/trunk/pypy/translator/geninterplevel.py Thu Mar 18 14:42:08 2010 @@ -194,8 +194,8 @@ def __repr__(self): return '<%s>' % self.__name__ - self.builtin_ids = identity_dict() - self.builtin_ids.update([ + self.ibuiltin_ids = identity_dict() + self.ibuiltin_ids.update([ (value, bltinstub(key)) for key, value in __builtin__.__dict__.items() if callable(value) and type(value) not in [types.ClassType, type] ] ) @@ -392,8 +392,8 @@ name = self.nameof_instance(obj) else: # shortcutting references to __builtin__ - if obj in self.builtin_ids: - func = self.builtin_ids[obj] + if obj in self.ibuiltin_ids: + func = self.ibuiltin_ids[obj] #name = self.get_nameof_builtin_func(func) # the above is quicker in principle, but pulls more # stuff in, so it is slower right now. @@ -706,8 +706,8 @@ return self._space_arities def try_space_shortcut_for_builtin(self, v, nargs, args): - if isinstance(v, Constant) and v.value in self.builtin_ids: - name = self.builtin_ids[v.value].__name__ + if isinstance(v, Constant) and v.value in self.ibuiltin_ids: + name = self.ibuiltin_ids[v.value].__name__ if hasattr(self.space, name): if self.space_arities().get(name, -1) == nargs: if name != 'isinstance': @@ -727,8 +727,8 @@ def nameof_builtin_function(self, func): # builtin function - if func in self.builtin_ids: - func = self.builtin_ids[func] + if func in self.ibuiltin_ids: + func = self.ibuiltin_ids[func] return "(space.builtin.get(space.str_w(%s)))" % self.nameof(func.__name__) # where does it come from? Python2.2 doesn't have func.__module__ for modname, module in sys.modules.items(): From arigo at codespeak.net Thu Mar 18 14:46:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 14:46:55 +0100 (CET) Subject: [pypy-svn] r72374 - pypy/trunk/pypy/translator/c Message-ID: <20100318134655.10831282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 14:46:54 2010 New Revision: 72374 Modified: pypy/trunk/pypy/translator/c/funcgen.py Log: Oups. This belongs to r72373. Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Thu Mar 18 14:46:54 2010 @@ -32,7 +32,7 @@ exception_policy more_ll_values vars all_cached_consts - lltypes + illtypes functionname blocknum innerloops From arigo at codespeak.net Thu Mar 18 15:40:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 15:40:33 +0100 (CET) Subject: [pypy-svn] r72375 - in pypy/trunk/pypy: module/_rawffi module/_rawffi/test rlib rlib/test Message-ID: <20100318144033.189E9282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 15:40:31 2010 New Revision: 72375 Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py pypy/trunk/pypy/rlib/libffi.py pypy/trunk/pypy/rlib/test/test_libffi.py Log: Fix an issue with CDLL() not reporting errors on top of PyPy. Done with a custom DLOpenError exception at interp-level. Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/trunk/pypy/module/_rawffi/interp_rawffi.py Thu Mar 18 15:40:31 2010 @@ -144,7 +144,11 @@ class W_CDLL(Wrappable): def __init__(self, space, name): - self.cdll = CDLL(name) + try: + self.cdll = CDLL(name) + except DLOpenError, e: + raise operationerrfmt(space.w_OSError, '%s: %s', name, + e.msg or 'unspecified error') self.name = name self.w_cache = space.newdict() self.space = space 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 Mar 18 15:40:31 2010 @@ -188,6 +188,16 @@ import _rawffi _rawffi.CDLL(self.libc_name) + def test_libload_fail(self): + import _rawffi + try: + _rawffi.CDLL("xxxxx_this_name_does_not_exist_xxxxx") + except OSError, e: + print e + assert str(e).startswith("xxxxx_this_name_does_not_exist_xxxxx: ") + else: + raise AssertionError("did not fail??") + def test_libc_load(self): import _rawffi _rawffi.get_libc() Modified: pypy/trunk/pypy/rlib/libffi.py ============================================================================== --- pypy/trunk/pypy/rlib/libffi.py (original) +++ pypy/trunk/pypy/rlib/libffi.py Thu Mar 18 15:40:31 2010 @@ -15,10 +15,6 @@ import sys 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 - from pypy.translator.platform import platform # maaaybe isinstance here would be better. Think @@ -218,6 +214,13 @@ def winexternal(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win') +class DLOpenError(Exception): + def __init__(self, msg): + self.msg = msg + def __str__(self): + return repr(self.msg) + + if not _WIN32: c_dlopen = external('dlopen', [rffi.CCHARP, rffi.INT], rffi.VOIDP) c_dlclose = external('dlclose', [rffi.VOIDP], rffi.INT) @@ -248,12 +251,7 @@ res = c_dlopen(name, rffi.cast(rffi.INT, mode)) if not res: err = dlerror() - # because the message would be lost in a translated program (OSError only has an errno), - # we offer a way to write it to stderr - if DEBUG: - import os - os.write(2, err) - raise OSError(-1, err) + raise DLOpenError(err) return res dlclose = c_dlclose @@ -284,8 +282,8 @@ def dlopen(name): res = rwin32.LoadLibrary(name) if not res: - # XXX format error message - raise WindowsError(2, rwin32.GetLastError()) + err = rwin32.GetLastError() + raise DLOpenError(rwin32.FormatError(err)) return res def dlclose(handle): @@ -626,6 +624,7 @@ class CDLL: def __init__(self, libname, unload_on_finalization=True): + """Load the library, or raises DLOpenError.""" self.unload_on_finalization = unload_on_finalization self.lib = lltype.nullptr(rffi.CCHARP.TO) ll_libname = rffi.str2charp(libname) 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 Mar 18 15:40:31 2010 @@ -24,7 +24,7 @@ ALLOCATED.clear() def test_dlopen(self): - py.test.raises(OSError, "dlopen(rffi.str2charp('xxxxxxxxxxxx'))") + py.test.raises(DLOpenError, "dlopen(rffi.str2charp('xxxxxxxxxxxx'))") assert dlopen(rffi.str2charp(get_libc_name())) def get_libc(self): From afa at codespeak.net Thu Mar 18 15:43:02 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 18 Mar 2010 15:43:02 +0100 (CET) Subject: [pypy-svn] r72376 - pypy/trunk/pypy/rpython/lltypesystem Message-ID: <20100318144302.36AD9282BDB@codespeak.net> Author: afa Date: Thu Mar 18 15:43:00 2010 New Revision: 72376 Modified: pypy/trunk/pypy/rpython/lltypesystem/opimpl.py Log: AddressOffsets are legitimate in op_int_floordiv() and op_int_mod(), but cannot be be constant-folded. Change the assert, let the next line raise TypeError, so no warning will be printed. Modified: pypy/trunk/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/opimpl.py Thu Mar 18 15:43:00 2010 @@ -210,16 +210,16 @@ return intmask(x * y) def op_int_floordiv(x, y): - assert isinstance(x, int) - assert isinstance(y, int) + assert isinstance(x, (int, llmemory.AddressOffset)) + assert isinstance(y, (int, llmemory.AddressOffset)) r = x//y if x^y < 0 and x%y != 0: r += 1 return r def op_int_mod(x, y): - assert isinstance(x, int) - assert isinstance(y, int) + assert isinstance(x, (int, llmemory.AddressOffset)) + assert isinstance(y, (int, llmemory.AddressOffset)) r = x%y if x^y < 0 and x%y != 0: r -= y From arigo at codespeak.net Thu Mar 18 16:21:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 16:21:22 +0100 (CET) Subject: [pypy-svn] r72379 - pypy/trunk/pypy/jit/backend/test Message-ID: <20100318152122.20B43282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 16:21:21 2010 New Revision: 72379 Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py Log: Add a test for the result of float operations over all possible combinations of infinities and NaNs. Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Thu Mar 18 16:21:21 2010 @@ -1,5 +1,5 @@ -import py, sys, random, os, struct +import py, sys, random, os, struct, operator from pypy.jit.metainterp.history import (AbstractFailDescr, BasicFailDescr, BoxInt, Box, BoxPtr, @@ -1007,6 +1007,62 @@ fail = self.cpu.execute_token(looptoken) assert fail.identifier == 1 + def test_nan_and_infinity(self): + if not self.cpu.supports_floats: + py.test.skip("requires floats") + + from pypy.rlib.rarithmetic import INFINITY, NAN, isinf, isnan + + fzer = BoxFloat(0.0) + fone = BoxFloat(1.0) + fmqr = BoxFloat(-0.25) + finf = BoxFloat(INFINITY) + fmnf = BoxFloat(-INFINITY) + fnan = BoxFloat(NAN) + + all_cases_unary = [(a,) for a in [fzer,fone,fmqr,finf,fmnf,fnan]] + all_cases_binary = [(a, b) for a in [fzer,fone,fmqr,finf,fmnf,fnan] + for b in [fzer,fone,fmqr,finf,fmnf,fnan]] + no_zero_divison = [(a, b) for a in [fzer,fone,fmqr,finf,fmnf,fnan] + for b in [ fone,fmqr,finf,fmnf,fnan]] + + def nan_and_infinity(opnum, realoperation, testcases): + for testcase in testcases: + realvalues = [b.value for b in testcase] + expected = realoperation(*realvalues) + if isinstance(expected, float): + expectedtype = 'float' + else: + expectedtype = 'int' + got = self.execute_operation(opnum, list(testcase), + expectedtype) + if isnan(expected): + ok = isnan(got.value) + elif isinf(expected): + ok = isinf(got.value) + else: + ok = (got.value == expected) + if not ok: + from pypy.jit.metainterp.resoperation import opname + raise AssertionError("%s(%s): got %r, expected %r" % ( + opname[opnum], ', '.join(map(repr, realvalues)), + got.value, expected)) + + yield nan_and_infinity, rop.FLOAT_ADD, operator.add, all_cases_binary + yield nan_and_infinity, rop.FLOAT_SUB, operator.sub, all_cases_binary + yield nan_and_infinity, rop.FLOAT_MUL, operator.mul, all_cases_binary + yield nan_and_infinity, rop.FLOAT_TRUEDIV, \ + operator.truediv, no_zero_divison + yield nan_and_infinity, rop.FLOAT_NEG, operator.neg, all_cases_unary + yield nan_and_infinity, rop.FLOAT_ABS, abs, all_cases_unary + yield nan_and_infinity, rop.FLOAT_IS_TRUE, bool, all_cases_unary + yield nan_and_infinity, rop.FLOAT_LT, operator.lt, all_cases_binary + yield nan_and_infinity, rop.FLOAT_LE, operator.le, all_cases_binary + yield nan_and_infinity, rop.FLOAT_EQ, operator.eq, all_cases_binary + yield nan_and_infinity, rop.FLOAT_NE, operator.ne, all_cases_binary + yield nan_and_infinity, rop.FLOAT_GT, operator.gt, all_cases_binary + yield nan_and_infinity, rop.FLOAT_GE, operator.ge, all_cases_binary + class LLtypeBackendTest(BaseBackendTest): From arigo at codespeak.net Thu Mar 18 16:35:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 16:35:34 +0100 (CET) Subject: [pypy-svn] r72382 - pypy/trunk/pypy/jit/backend/test Message-ID: <20100318153534.C3DD6282BDE@codespeak.net> Author: arigo Date: Thu Mar 18 16:35:33 2010 New Revision: 72382 Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py Log: Improve the test. Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Thu Mar 18 16:35:33 2010 @@ -1047,6 +1047,26 @@ raise AssertionError("%s(%s): got %r, expected %r" % ( opname[opnum], ', '.join(map(repr, realvalues)), got.value, expected)) + # if we expect a boolean, also check the combination with + # a GUARD_TRUE or GUARD_FALSE + if isinstance(expected, bool): + for guard_opnum, expected_id in [(rop.GUARD_TRUE, 1), + (rop.GUARD_FALSE, 0)]: + box = BoxInt() + operations = [ + ResOperation(opnum, list(testcase), box), + ResOperation(guard_opnum, [box], None, + descr=BasicFailDescr(4)), + ResOperation(rop.FINISH, [], None, + descr=BasicFailDescr(5))] + operations[1].fail_args = [] + looptoken = LoopToken() + self.cpu.compile_loop(list(testcase), operations, + looptoken) + for i, box in enumerate(testcase): + self.cpu.set_future_value_float(i, box.value) + fail = self.cpu.execute_token(looptoken) + assert fail.identifier == 5 - (expected_id ^ expected) yield nan_and_infinity, rop.FLOAT_ADD, operator.add, all_cases_binary yield nan_and_infinity, rop.FLOAT_SUB, operator.sub, all_cases_binary From fijal at codespeak.net Thu Mar 18 16:59:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 16:59:15 +0100 (CET) Subject: [pypy-svn] r72383 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100318155915.62489282BDB@codespeak.net> Author: fijal Date: Thu Mar 18 16:59:13 2010 New Revision: 72383 Modified: pypy/trunk/pypy/jit/backend/x86/ri386.py Log: create higher8bits (it's bits 8-16) Modified: pypy/trunk/pypy/jit/backend/x86/ri386.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/ri386.py (original) +++ pypy/trunk/pypy/jit/backend/x86/ri386.py Thu Mar 18 16:59:13 2010 @@ -16,8 +16,11 @@ def lowest8bits(self): if self.op < 4: return registers8[self.op] - else: - raise ValueError + raise ValueError + def higher8bits(self): + if self.op < 4: + return registers8[self.op + 4] + raise ValueError class FLOATREG(OPERAND): width = 8 From fijal at codespeak.net Thu Mar 18 17:05:37 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 17:05:37 +0100 (CET) Subject: [pypy-svn] r72384 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100318160537.45884282BDB@codespeak.net> Author: fijal Date: Thu Mar 18 17:05:36 2010 New Revision: 72384 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: Fix float_is_true - first part Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Thu Mar 18 17:05:36 2010 @@ -682,8 +682,12 @@ loc0, loc1 = arglocs self.mc.XORPD(loc0, loc0) self.mc.UCOMISD(loc0, loc1) - self.mc.SETNE(lower_byte(resloc)) - self.mc.MOVZX(resloc, lower_byte(resloc)) + rl = resloc.lowest8bits() + rh = resloc.higher8bits() + self.mc.SETNE(rl) + self.mc.SETP(rh) + self.mc.OR(rl, rh) + self.mc.MOVZX(resloc, rl) def genop_cast_float_to_int(self, op, arglocs, resloc): self.mc.CVTTSD2SI(resloc, arglocs[0]) From arigo at codespeak.net Thu Mar 18 17:16:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 17:16:20 +0100 (CET) Subject: [pypy-svn] r72385 - pypy/trunk/pypy/jit/backend/test Message-ID: <20100318161620.E6305282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 17:16:19 2010 New Revision: 72385 Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py Log: Improve test reporting. Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Thu Mar 18 17:16:19 2010 @@ -1012,6 +1012,7 @@ py.test.skip("requires floats") from pypy.rlib.rarithmetic import INFINITY, NAN, isinf, isnan + from pypy.jit.metainterp.resoperation import opname fzer = BoxFloat(0.0) fone = BoxFloat(1.0) @@ -1043,7 +1044,6 @@ else: ok = (got.value == expected) if not ok: - from pypy.jit.metainterp.resoperation import opname raise AssertionError("%s(%s): got %r, expected %r" % ( opname[opnum], ', '.join(map(repr, realvalues)), got.value, expected)) @@ -1066,7 +1066,16 @@ for i, box in enumerate(testcase): self.cpu.set_future_value_float(i, box.value) fail = self.cpu.execute_token(looptoken) - assert fail.identifier == 5 - (expected_id ^ expected) + if fail.identifier != 5 - (expected_id^expected): + if fail.identifier == 4: + msg = "it was taken" + else: + msg = "it was not taken" + raise AssertionError( + "%s(%s)/%s took the wrong path: %s" % ( + opname[opnum], + ', '.join(map(repr, realvalues)), + opname[guard_opnum], msg)) yield nan_and_infinity, rop.FLOAT_ADD, operator.add, all_cases_binary yield nan_and_infinity, rop.FLOAT_SUB, operator.sub, all_cases_binary From arigo at codespeak.net Thu Mar 18 17:40:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Mar 2010 17:40:59 +0100 (CET) Subject: [pypy-svn] r72389 - pypy/trunk/pypy/jit/backend/test Message-ID: <20100318164059.764E8282BDB@codespeak.net> Author: arigo Date: Thu Mar 18 17:40:57 2010 New Revision: 72389 Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py Log: Tweak the error message we get to be more explicit. Modified: pypy/trunk/pypy/jit/backend/test/runner_test.py ============================================================================== --- pypy/trunk/pypy/jit/backend/test/runner_test.py (original) +++ pypy/trunk/pypy/jit/backend/test/runner_test.py Thu Mar 18 17:40:57 2010 @@ -1068,11 +1068,12 @@ fail = self.cpu.execute_token(looptoken) if fail.identifier != 5 - (expected_id^expected): if fail.identifier == 4: - msg = "it was taken" + msg = "was taken" else: - msg = "it was not taken" + msg = "was not taken" raise AssertionError( - "%s(%s)/%s took the wrong path: %s" % ( + "%s(%s)/%s took the wrong path: " + "the failure path of the guard %s" % ( opname[opnum], ', '.join(map(repr, realvalues)), opname[guard_opnum], msg)) From afa at codespeak.net Thu Mar 18 17:50:10 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 18 Mar 2010 17:50:10 +0100 (CET) Subject: [pypy-svn] r72390 - pypy/trunk/pypy/rpython Message-ID: <20100318165010.6902F282BDB@codespeak.net> Author: afa Date: Thu Mar 18 17:50:08 2010 New Revision: 72390 Modified: pypy/trunk/pypy/rpython/rclass.py Log: Simplify the identity_dict: no need to store the key in the value! Modified: pypy/trunk/pypy/rpython/rclass.py ============================================================================== --- pypy/trunk/pypy/rpython/rclass.py (original) +++ pypy/trunk/pypy/rpython/rclass.py Thu Mar 18 17:50:08 2010 @@ -223,11 +223,11 @@ def convert_const_exact(self, value): try: - return self.iprebuiltinstances[value][1] + return self.iprebuiltinstances[value] except KeyError: self.setup() result = self.create_instance() - self.iprebuiltinstances[value] = value, result + self.iprebuiltinstances[value] = result self.initialize_prebuilt_instance(value, self.classdef, result) return result From fijal at codespeak.net Thu Mar 18 18:39:48 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 18:39:48 +0100 (CET) Subject: [pypy-svn] r72394 - pypy/build/bot2/pypybuildbot Message-ID: <20100318173948.DA2E6282BDB@codespeak.net> Author: fijal Date: Thu Mar 18 18:39:47 2010 New Revision: 72394 Modified: pypy/build/bot2/pypybuildbot/builds.py Log: According to exarkun, higher blocksize is required to avoid problems Modified: pypy/build/bot2/pypybuildbot/builds.py ============================================================================== --- pypy/build/bot2/pypybuildbot/builds.py (original) +++ pypy/build/bot2/pypybuildbot/builds.py Thu Mar 18 18:39:47 2010 @@ -112,9 +112,10 @@ # upload nightly build, if we're running jit tests nightly = os.path.expanduser('~/nightly/pypy-c-jit-%(got_revision)s-' + platform) pypy_c_rel = 'build/pypy/translator/goal/pypy-c' - #self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, - # masterdest=WithProperties(nightly), - # workdir='.')) + self.addStep(transfer.FileUpload(slavesrc=pypy_c_rel, + masterdest=WithProperties(nightly), + workdir='.', + blocksize=100*1024)) self.addStep(ShellCmd( description="pypyjit tests", command=["python", "pypy/test_all.py", From fijal at codespeak.net Thu Mar 18 21:22:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 21:22:36 +0100 (CET) Subject: [pypy-svn] r72398 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100318202236.68C86282BE0@codespeak.net> Author: fijal Date: Thu Mar 18 21:22:28 2010 New Revision: 72398 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: Enough to pass float_is_true tests Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Thu Mar 18 21:22:28 2010 @@ -282,7 +282,7 @@ faildescr._x86_bridge_frame_depth = frame_depth faildescr._x86_bridge_param_depth = param_depth # patch the jump from original guard - self.patch_jump(faildescr, adr_bridge) + self.patch_jump_for_descr(faildescr, adr_bridge) debug_print("Bridge out of guard", descr_number, "has address", adr_bridge, "to", self.mc.tell()) @@ -295,8 +295,13 @@ return "" - def patch_jump(self, faildescr, adr_new_target): + def patch_jump_for_descr(self, faildescr, adr_new_target): adr_jump_offset = faildescr._x86_adr_jump_offset + self.patch_jump(faildescr._x86_adr_jump_offset, adr_new_target) + if faildescr._x86_adr_jump_offset2: + self.patch_jump(faildescr._x86_adr_jump_offset2, adr_new_target) + + def patch_jump(self, adr_jump_offset, adr_new_target): mc = codebuf.InMemoryCodeBuilder(adr_jump_offset, adr_jump_offset + 4) mc.write(packimm32(adr_new_target - adr_jump_offset - 4)) mc.valgrind_invalidated() @@ -491,11 +496,11 @@ dispatch_opnum = guard_opnum else: dispatch_opnum = op.opnum - adr_jump_offset = genop_guard_list[dispatch_opnum](self, op, - guard_op, - failaddr, arglocs, - resloc) + t = genop_guard_list[dispatch_opnum](self, op, guard_op, failaddr, + arglocs, resloc) + adr_jump_offset, adr_jump_offset2 = t faildescr._x86_adr_jump_offset = adr_jump_offset + faildescr._x86_adr_jump_offset2 = adr_jump_offset2 def regalloc_perform_guard(self, guard_op, faillocs, arglocs, resloc, current_depths): @@ -540,18 +545,18 @@ self.mc.CMP(arglocs[1], arglocs[0]) if guard_opnum == rop.GUARD_FALSE: name = 'J' + rev_cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 else: name = 'J' + false_rev_cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 else: self.mc.CMP(arglocs[0], arglocs[1]) if guard_opnum == rop.GUARD_FALSE: name = 'J' + cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 else: name = 'J' + false_cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 return genop_cmp_guard def _cmpop_guard_float(cond, false_cond): @@ -561,10 +566,10 @@ self.mc.UCOMISD(arglocs[0], arglocs[1]) if guard_opnum == rop.GUARD_FALSE: name = 'J' + cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 else: name = 'J' + false_cond - return self.implement_guard(addr, getattr(self.mc, name)) + return self.implement_guard(addr, getattr(self.mc, name)), 0 return genop_cmp_guard_float @specialize.arg(5) @@ -674,9 +679,14 @@ self.mc.XORPD(loc0, loc0) self.mc.UCOMISD(loc0, loc1) if guard_opnum == rop.GUARD_TRUE: - return self.implement_guard(addr, self.mc.JZ) + mc = self.mc._mc + mc.JP(rel32(mc.tell() + 2*6)) + mc.JZ(rel32(addr)) + return mc.tell() - 4, 0 else: - return self.implement_guard(addr, self.mc.JNZ) + addr1 = self.implement_guard(addr, self.mc.JNZ) + addr2 = self.implement_guard(addr, self.mc.JP) + return addr1, addr2 def genop_float_is_true(self, op, arglocs, resloc): loc0, loc1 = arglocs @@ -717,9 +727,9 @@ guard_opnum = guard_op.opnum self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: - return self.implement_guard(addr, self.mc.JZ) + return self.implement_guard(addr, self.mc.JZ), 0 else: - return self.implement_guard(addr, self.mc.JNZ) + return self.implement_guard(addr, self.mc.JNZ), 0 def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) @@ -730,9 +740,9 @@ guard_opnum = guard_op.opnum self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: - return self.implement_guard(addr, self.mc.JNZ) + return self.implement_guard(addr, self.mc.JNZ), 0 else: - return self.implement_guard(addr, self.mc.JZ) + return self.implement_guard(addr, self.mc.JZ), 0 def genop_bool_not(self, op, arglocs, resloc): self.mc.XOR(arglocs[0], imm8(1)) @@ -915,13 +925,13 @@ def genop_guard_guard_true(self, ign_1, guard_op, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) - return self.implement_guard(addr, self.mc.JZ) + return self.implement_guard(addr, self.mc.JZ), 0 genop_guard_guard_nonnull = genop_guard_guard_true def genop_guard_guard_no_exception(self, ign_1, guard_op, addr, locs, ign_2): self.mc.CMP(heap(self.cpu.pos_exception()), imm(0)) - return self.implement_guard(addr, self.mc.JNZ) + return self.implement_guard(addr, self.mc.JNZ), 0 def genop_guard_guard_exception(self, ign_1, guard_op, addr, locs, resloc): @@ -934,20 +944,20 @@ self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) self.mc.MOV(heap(self.cpu.pos_exception()), imm(0)) self.mc.MOV(heap(self.cpu.pos_exc_value()), imm(0)) - return addr + return addr, 0 def genop_guard_guard_no_overflow(self, ign_1, guard_op, addr, locs, resloc): - return self.implement_guard(addr, self.mc.JO) + return self.implement_guard(addr, self.mc.JO), 0 def genop_guard_guard_overflow(self, ign_1, guard_op, addr, locs, resloc): - return self.implement_guard(addr, self.mc.JNO) + return self.implement_guard(addr, self.mc.JNO), 0 def genop_guard_guard_false(self, ign_1, guard_op, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) - return self.implement_guard(addr, self.mc.JNZ) + return self.implement_guard(addr, self.mc.JNZ), 0 genop_guard_guard_isnull = genop_guard_guard_false def genop_guard_guard_value(self, ign_1, guard_op, addr, locs, ign_2): @@ -956,7 +966,7 @@ self.mc.UCOMISD(locs[0], locs[1]) else: self.mc.CMP(locs[0], locs[1]) - return self.implement_guard(addr, self.mc.JNE) + return self.implement_guard(addr, self.mc.JNE), 0 def _cmp_guard_class(self, mc, locs): offset = self.cpu.vtable_offset @@ -982,7 +992,7 @@ mc = self._start_block() self._cmp_guard_class(mc, locs) self._stop_block() - return self.implement_guard(addr, self.mc.JNE) + return self.implement_guard(addr, self.mc.JNE), 0 def genop_guard_guard_nonnull_class(self, ign_1, guard_op, addr, locs, ign_2): @@ -997,7 +1007,7 @@ mc.overwrite(jb_location-1, [chr(offset)]) self._stop_block() # - return self.implement_guard(addr, self.mc.JNE) + return self.implement_guard(addr, self.mc.JNE), 0 def implement_guard_recovery(self, guard_opnum, faildescr, failargs, fail_locs): @@ -1373,7 +1383,7 @@ self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) self.genop_call(op, arglocs, result_loc) self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) - return self.implement_guard(addr, self.mc.JL) + return self.implement_guard(addr, self.mc.JL), 0 def genop_guard_call_assembler(self, op, guard_op, addr, arglocs, result_loc): @@ -1406,7 +1416,7 @@ else: assert result_loc is eax or result_loc is None self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) - return self.implement_guard(addr, self.mc.JL) + return self.implement_guard(addr, self.mc.JL), 0 def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid From fijal at codespeak.net Thu Mar 18 21:50:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 18 Mar 2010 21:50:36 +0100 (CET) Subject: [pypy-svn] r72399 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100318205036.6774F282BE0@codespeak.net> Author: fijal Date: Thu Mar 18 21:50:34 2010 New Revision: 72399 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: I think this is it for passing test_nan_and_infinity Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Thu Mar 18 21:50:34 2010 @@ -531,11 +531,19 @@ self.mc.MOVZX(result_loc, lower_byte(result_loc)) return genop_cmp - def _cmpop_float(cond): + def _cmpop_float(cond, is_ne=False): def genop_cmp(self, op, arglocs, result_loc): self.mc.UCOMISD(arglocs[0], arglocs[1]) - getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) - self.mc.MOVZX(result_loc, lower_byte(result_loc)) + rl = result_loc.lowest8bits() + rh = result_loc.higher8bits() + getattr(self.mc, 'SET' + cond)(rl) + if is_ne: + self.mc.SETP(rh) + self.mc.OR(rl, rh) + else: + self.mc.SETNP(rh) + self.mc.AND(rl, rh) + self.mc.MOVZX(result_loc, rl) return genop_cmp def _cmpop_guard(cond, rev_cond, false_cond, false_rev_cond): @@ -565,11 +573,16 @@ guard_opnum = guard_op.opnum self.mc.UCOMISD(arglocs[0], arglocs[1]) if guard_opnum == rop.GUARD_FALSE: + mc = self.mc._mc name = 'J' + cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + mc.JP(rel32(mc.tell() + 12)) + getattr(mc, name)(rel32(addr)) + return mc.tell() - 4, 0 else: name = 'J' + false_cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + addr1 = self.implement_guard(addr, getattr(self.mc, name)) + addr2 = self.implement_guard(addr, self.mc.JP) + return addr1, addr2 return genop_cmp_guard_float @specialize.arg(5) @@ -634,8 +647,8 @@ genop_float_lt = _cmpop_float('B') genop_float_le = _cmpop_float('BE') + genop_float_ne = _cmpop_float('NE', is_ne=True) genop_float_eq = _cmpop_float('E') - genop_float_ne = _cmpop_float('NE') genop_float_gt = _cmpop_float('A') genop_float_ge = _cmpop_float('AE') @@ -661,10 +674,22 @@ genop_guard_float_lt = _cmpop_guard_float("B", "AE") genop_guard_float_le = _cmpop_guard_float("BE", "A") genop_guard_float_eq = _cmpop_guard_float("E", "NE") - genop_guard_float_ne = _cmpop_guard_float("NE", "E") genop_guard_float_gt = _cmpop_guard_float("A", "BE") genop_guard_float_ge = _cmpop_guard_float("AE", "B") + def genop_guard_float_ne(self, op, guard_op, addr, arglocs, result_loc): + guard_opnum = guard_op.opnum + self.mc.UCOMISD(arglocs[0], arglocs[1]) + if guard_opnum == rop.GUARD_TRUE: + mc = self.mc._mc + mc.JP(rel32(mc.tell() + 12)) + mc.JE(rel32(addr)) + return mc.tell() - 4, 0 + else: + addr1 = self.implement_guard(addr, self.mc.JNE) + addr2 = self.implement_guard(addr, self.mc.JP) + return addr1, addr2 + def genop_float_neg(self, op, arglocs, resloc): # Following what gcc does: res = x ^ 0x8000000000000000 self.mc.XORPD(arglocs[0], self.loc_float_const_neg) From benjamin at codespeak.net Thu Mar 18 23:54:24 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Thu, 18 Mar 2010 23:54:24 +0100 (CET) Subject: [pypy-svn] r72400 - in pypy/trunk: lib-python/modified-2.5.2/distutils pypy/lib pypy/rpython/lltypesystem/module/test Message-ID: <20100318225424.A09F8282BDB@codespeak.net> Author: benjamin Date: Thu Mar 18 23:54:21 2010 New Revision: 72400 Modified: pypy/trunk/lib-python/modified-2.5.2/distutils/sysconfig.py (props changed) pypy/trunk/pypy/lib/identity_dict.py (props changed) pypy/trunk/pypy/rpython/lltypesystem/module/test/test_ll_math.py (props changed) Log: set svn:eol-style From fijal at codespeak.net Fri Mar 19 03:27:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 03:27:58 +0100 (CET) Subject: [pypy-svn] r72401 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100319022758.C7999282BDB@codespeak.net> Author: fijal Date: Fri Mar 19 03:27:56 2010 New Revision: 72401 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/regalloc.py Log: kill lower_byte, use official interface instead Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 03:27:56 2010 @@ -7,7 +7,7 @@ from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.tool.uid import fixid -from pypy.jit.backend.x86.regalloc import RegAlloc, WORD, lower_byte,\ +from pypy.jit.backend.x86.regalloc import RegAlloc, WORD,\ X86RegisterManager, X86XMMRegisterManager, get_ebp_ofs, FRAME_FIXED_SIZE,\ FORCE_INDEX_OFS from pypy.rlib.objectmodel import we_are_translated, specialize @@ -522,13 +522,14 @@ def _cmpop(cond, rev_cond): def genop_cmp(self, op, arglocs, result_loc): + rl = result_loc.lowest8bits() if isinstance(op.args[0], Const): self.mc.CMP(arglocs[1], arglocs[0]) - getattr(self.mc, 'SET' + rev_cond)(lower_byte(result_loc)) + getattr(self.mc, 'SET' + rev_cond)(rl) else: self.mc.CMP(arglocs[0], arglocs[1]) - getattr(self.mc, 'SET' + cond)(lower_byte(result_loc)) - self.mc.MOVZX(result_loc, lower_byte(result_loc)) + getattr(self.mc, 'SET' + cond)(rl) + self.mc.MOVZX(result_loc, rl) return genop_cmp def _cmpop_float(cond, is_ne=False): @@ -758,8 +759,9 @@ def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) - self.mc.SETNE(lower_byte(resloc)) - self.mc.MOVZX(resloc, lower_byte(resloc)) + rl = resloc.lowest8bits() + self.mc.SETNE(rl) + self.mc.MOVZX(resloc, rl) def genop_guard_bool_not(self, op, guard_op, addr, arglocs, resloc): guard_opnum = guard_op.opnum @@ -868,7 +870,7 @@ elif size == 2: self.mc.MOV16(addr_add(base_loc, ofs_loc), value_loc) elif size == 1: - self.mc.MOV(addr8_add(base_loc, ofs_loc), lower_byte(value_loc)) + self.mc.MOV(addr8_add(base_loc, ofs_loc), value_loc.lowest8bits()) else: print "[asmgen]setfield addr size %d" % size raise NotImplementedError("Addr size %d" % size) @@ -886,7 +888,7 @@ scale_loc.value), value_loc) elif scale_loc.value == 0: self.mc.MOV(addr8_add(base_loc, ofs_loc, baseofs.value, - scale_loc.value), lower_byte(value_loc)) + scale_loc.value), value_loc.lowest8bits()) else: raise NotImplementedError("scale = %d" % scale_loc.value) @@ -896,7 +898,7 @@ self.cpu.translate_support_code) assert itemsize == 1 self.mc.MOV(addr8_add(base_loc, ofs_loc, basesize), - lower_byte(val_loc)) + val_loc.lowest8bits()) def genop_discard_unicodesetitem(self, op, arglocs): base_loc, ofs_loc, val_loc = arglocs Modified: pypy/trunk/pypy/jit/backend/x86/regalloc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/regalloc.py (original) +++ pypy/trunk/pypy/jit/backend/x86/regalloc.py Fri Mar 19 03:27:56 2010 @@ -1011,20 +1011,3 @@ # Returns (ebp-20), (ebp-24), (ebp-28)... # i.e. the n'th word beyond the fixed frame size. return -WORD * (FRAME_FIXED_SIZE + position) - -def lower_byte(reg): - # argh, kill, use lowest8bits instead - if isinstance(reg, MODRM): - return reg - if isinstance(reg, IMM32): - return imm8(reg.value) - if reg is eax: - return al - elif reg is ebx: - return bl - elif reg is ecx: - return cl - elif reg is edx: - return dl - else: - raise NotImplementedError() From arigo at codespeak.net Fri Mar 19 03:31:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Mar 2010 03:31:58 +0100 (CET) Subject: [pypy-svn] r72402 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100319023158.4B95B282BDB@codespeak.net> Author: arigo Date: Fri Mar 19 03:31:56 2010 New Revision: 72402 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: Minimal change to avoid JP in case it's not needed. A slightly larger change would be to remove JP also for GUARD_LT and GUARD_LE, by exchanging the two arguments so that they become GUARD_GT and GUARD_GE. Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 03:31:56 2010 @@ -568,7 +568,7 @@ return self.implement_guard(addr, getattr(self.mc, name)), 0 return genop_cmp_guard - def _cmpop_guard_float(cond, false_cond): + def _cmpop_guard_float(cond, false_cond, need_jp): def genop_cmp_guard_float(self, op, guard_op, addr, arglocs, result_loc): guard_opnum = guard_op.opnum @@ -576,13 +576,17 @@ if guard_opnum == rop.GUARD_FALSE: mc = self.mc._mc name = 'J' + cond - mc.JP(rel32(mc.tell() + 12)) + if need_jp: + mc.JP(rel32(mc.tell() + 12)) getattr(mc, name)(rel32(addr)) return mc.tell() - 4, 0 else: name = 'J' + false_cond addr1 = self.implement_guard(addr, getattr(self.mc, name)) - addr2 = self.implement_guard(addr, self.mc.JP) + if need_jp: + addr2 = self.implement_guard(addr, self.mc.JP) + else: + addr2 = 0 return addr1, addr2 return genop_cmp_guard_float @@ -672,11 +676,11 @@ genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B") genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A") - genop_guard_float_lt = _cmpop_guard_float("B", "AE") - genop_guard_float_le = _cmpop_guard_float("BE", "A") - genop_guard_float_eq = _cmpop_guard_float("E", "NE") - genop_guard_float_gt = _cmpop_guard_float("A", "BE") - genop_guard_float_ge = _cmpop_guard_float("AE", "B") + genop_guard_float_lt = _cmpop_guard_float("B", "AE", True) + genop_guard_float_le = _cmpop_guard_float("BE", "A", True) + genop_guard_float_eq = _cmpop_guard_float("E", "NE", True) + genop_guard_float_gt = _cmpop_guard_float("A", "BE", False) + genop_guard_float_ge = _cmpop_guard_float("AE", "B", False) def genop_guard_float_ne(self, op, guard_op, addr, arglocs, result_loc): guard_opnum = guard_op.opnum From fijal at codespeak.net Fri Mar 19 04:38:14 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 04:38:14 +0100 (CET) Subject: [pypy-svn] r72403 - in pypy/trunk/pypy/jit/backend/x86: . test Message-ID: <20100319033814.D39CA282BDB@codespeak.net> Author: fijal Date: Fri Mar 19 04:38:13 2010 New Revision: 72403 Modified: pypy/trunk/pypy/jit/backend/x86/ri386.py pypy/trunk/pypy/jit/backend/x86/ri386setup.py pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Log: Add rel8 to JMP and Jxx. Apparently tests are happy, although I'm not 100% sure if I did the right thing Modified: pypy/trunk/pypy/jit/backend/x86/ri386.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/ri386.py (original) +++ pypy/trunk/pypy/jit/backend/x86/ri386.py Fri Mar 19 04:38:13 2010 @@ -207,12 +207,19 @@ class MODRM8(MODRM): width = 1 -class REL32(OPERAND): - width = 4 +class REL(OPERAND): def __init__(self, absolute_target): self.absolute_target = absolute_target def assembler(self): - return '%d' % (self.absolute_target,) + return '%d' % (self.absolute_target,) + +class REL32(REL): + width = 4 + +class REL8(REL): + def assembler(self): + return '.+%d' % (self.absolute_target,) + width = 1 class MISSING(OPERAND): def __repr__(self): @@ -274,6 +281,7 @@ imm8 = IMM8 imm16 = IMM16 rel32 = REL32 +rel8 = REL8 def imm(value): if isinstance(value, ComputedIntSymbolic): Modified: pypy/trunk/pypy/jit/backend/x86/ri386setup.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/ri386setup.py (original) +++ pypy/trunk/pypy/jit/backend/x86/ri386setup.py Fri Mar 19 04:38:13 2010 @@ -44,6 +44,7 @@ IMM8: [(IMM8, None), (IMM32, None)], REL32: [(REL32, None)], + REL8: [(REL8, None)], MODRM: [(MODRM, None)], MODRM8: [(MODRM8, None)], @@ -103,16 +104,23 @@ elif self.width == 'h': lines.append('builder.write(packimm16(arg%d.value))' % (self.op,)) else: - raise AssertionError, "invalid width %r" % (self.width,) + raise ValueError("invalid width %r" % (self.width,)) return False class relative(operand): def eval(self, lines, has_orbyte): assert not has_orbyte, "malformed bytecode" - assert self.width == 'i', "only REL32 supported at the moment" - lines.append('offset = arg%d.absolute_target - (builder.tell()+4)' % ( - self.op,)) - lines.append('builder.write(packimm32(offset))') + if self.width == 'i': + lines.append('offset = arg%d.absolute_target - (builder.tell()+4)' + % (self.op,)) + lines.append('builder.write(packimm32(offset))') + elif self.width == 'b': + lines.append('offset = arg%d.absolute_target - (builder.tell()+2)' + % (self.op,)) + lines.append('assert offset < 127') + lines.append('builder.write(packimm8(offset))') + else: + raise ValueError("Invalid width %s" % (self.width,)) return False ##class conditioncode(operand): @@ -329,7 +337,7 @@ CALL.indirect = 1 JMP = Instruction() -#JMP.mode1(REL8, ['\xEB', immediate(1,'b')]) +JMP.mode1(REL8, ['\xEB', relative(1,'b')]) JMP.mode1(REL32, ['\xE9', relative(1)]) JMP.mode1(MODRM, ['\xFF', orbyte(4<<3), modrm(1)]) JMP.indirect = 1 @@ -589,7 +597,7 @@ instr._mode(modes, code1) instr.indirect = indirect -#define_cond('J', 1, (REL8,), [None,'\x70', immediate(1,'b')]) +define_cond('J', 1, (REL8,), [None,'\x70', relative(1,'b')]) define_cond('J', 1, (REL32,), ['\x0F', None,'\x80', relative(1)]) define_cond('SET', 0, (MODRM8,), ['\x0F', None,'\x90',orbyte(0<<3),modrm(1,'b')]) define_cond('CMOV',0,(REG,MODRM),['\x0F', None,'\x40', register(1,8), modrm(2)]) Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Fri Mar 19 04:38:13 2010 @@ -40,7 +40,7 @@ i386.MODRM8: 1, i386.IMM8: 1, i386.IMM16: 2, - #i386.REL8: 1, + i386.REL8: 1, i386.REL32: 4, } @@ -56,6 +56,10 @@ v = [-128,-1,0,1,127] + [random.randrange(-127, 127) for i in range(COUNT1)] return map(i386.imm8, v) +def rel8_tests(): + v = [-1,0,1] + [random.randrange(-123, 123) for i in range(COUNT1)] + return map(i386.rel8, v) + def imm16_tests(): v = [-32768,32767] + [random.randrange(-32767, -128) for i in range(COUNT1)] \ + [random.randrange(128, 32767) for i in range(COUNT1)] @@ -125,7 +129,7 @@ i386.MODRM8: modrm8_tests, i386.IMM8: imm8_tests, i386.IMM16: imm16_tests, - #i386.REL8: imm8_tests, + i386.REL8: rel8_tests, i386.REL32: lambda: [], # XXX imm32_tests, } @@ -148,7 +152,7 @@ following = "" if instr.indirect: suffix = "" - if args[-1][0] == i386.REL32: #in (i386.REL8,i386.REL32): + if args[-1][0] in (i386.REL8,i386.REL32): labelcount += 1 following = "\nL%d:" % labelcount elif args[-1][0] in (i386.IMM8,i386.IMM32): @@ -160,7 +164,7 @@ else: k = len(args) for m, extra in args[:k]: - assert m != i386.REL32 #not in (i386.REL8,i386.REL32) + assert m not in (i386.REL8,i386.REL32) ops = [extra.assembler() for m, extra in args] ops.reverse() op = '\x09%s%s %s%s' % (instrname, suffix, string.join(ops, ", "), @@ -256,6 +260,9 @@ self.op = op self.instrindex = self.index + def tell(self): + return 0 + def write(self, listofchars): data = ''.join(listofchars) end = self.index+len(data) From fijal at codespeak.net Fri Mar 19 04:44:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 04:44:30 +0100 (CET) Subject: [pypy-svn] r72404 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100319034430.7E279282BDB@codespeak.net> Author: fijal Date: Fri Mar 19 04:44:28 2010 New Revision: 72404 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py Log: Kill obscure hacks Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 04:44:28 2010 @@ -1029,7 +1029,7 @@ addr, locs, ign_2): mc = self._start_block() mc.CMP(locs[0], imm8(1)) - mc.write(constlistofchars('\x72\x00')) # JB later + mc.JB(rel8(mc.tell())) jb_location = mc.get_relative_pos() self._cmp_guard_class(mc, locs) # patch the JB above @@ -1428,11 +1428,11 @@ tmp=eax) mc = self._start_block() mc.CMP(eax, imm(self.cpu.done_with_this_frame_int_v)) - mc.write(constlistofchars('\x74\x00')) # JE below + mc.JE(rel8(mc.tell())) je_location = mc.get_relative_pos() self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, tmp=ecx, force_mc=True, mc=mc) - mc.write(constlistofchars('\xEB\x00')) # JMP below + mc.JMP(rel8(mc.tell())) jmp_location = mc.get_relative_pos() offset = jmp_location - je_location assert 0 < offset <= 127 @@ -1460,7 +1460,7 @@ mc = self._start_block() mc.TEST(mem8(loc_base, descr.jit_wb_if_flag_byteofs), imm8(descr.jit_wb_if_flag_singlebyte)) - mc.write(constlistofchars('\x74\x00')) # JZ after_the_call + mc.JZ(rel8(mc.tell())) jz_location = mc.get_relative_pos() # the following is supposed to be the slow path, so whenever possible # we choose the most compact encoding over the most efficient one. @@ -1518,7 +1518,7 @@ mc.MOV(eax, heap(nursery_free_adr)) mc.LEA(edx, addr_add(eax, imm(size))) mc.CMP(edx, heap(nursery_top_adr)) - mc.write(constlistofchars('\x76\x00')) # JNA after the block + mc.JNA(rel8(mc.tell())) jmp_adr = mc.get_relative_pos() # See comments in _build_malloc_fixedsize_slowpath for the From arigo at codespeak.net Fri Mar 19 10:47:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Mar 2010 10:47:26 +0100 (CET) Subject: [pypy-svn] r72405 - in pypy/trunk/pypy/jit/backend/x86: . test Message-ID: <20100319094726.1138D282BE0@codespeak.net> Author: arigo Date: Fri Mar 19 10:47:20 2010 New Revision: 72405 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/ri386.py pypy/trunk/pypy/jit/backend/x86/ri386setup.py pypy/trunk/pypy/jit/backend/x86/test/test_ri386.py pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Log: Fix bugs in the offset computation and in the tests of Jcond instructions. Did not show up in actual code because we always patch the offset later anyway. So fixed it by making rel8() take as a argument directly the relative offset (in our case it's always 0, because we patch it later, but at least it makes sense for test_ri386_auto_encoding). Added a test in test_ri386.py too. Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 10:47:20 2010 @@ -1029,7 +1029,7 @@ addr, locs, ign_2): mc = self._start_block() mc.CMP(locs[0], imm8(1)) - mc.JB(rel8(mc.tell())) + mc.JB(rel8_patched_later) jb_location = mc.get_relative_pos() self._cmp_guard_class(mc, locs) # patch the JB above @@ -1428,11 +1428,11 @@ tmp=eax) mc = self._start_block() mc.CMP(eax, imm(self.cpu.done_with_this_frame_int_v)) - mc.JE(rel8(mc.tell())) + mc.JE(rel8_patched_later) je_location = mc.get_relative_pos() self._emit_call(rel32(self.assembler_helper_adr), [eax, arglocs[1]], 0, tmp=ecx, force_mc=True, mc=mc) - mc.JMP(rel8(mc.tell())) + mc.JMP(rel8_patched_later) jmp_location = mc.get_relative_pos() offset = jmp_location - je_location assert 0 < offset <= 127 @@ -1460,7 +1460,7 @@ mc = self._start_block() mc.TEST(mem8(loc_base, descr.jit_wb_if_flag_byteofs), imm8(descr.jit_wb_if_flag_singlebyte)) - mc.JZ(rel8(mc.tell())) + mc.JZ(rel8_patched_later) jz_location = mc.get_relative_pos() # the following is supposed to be the slow path, so whenever possible # we choose the most compact encoding over the most efficient one. @@ -1518,7 +1518,7 @@ mc.MOV(eax, heap(nursery_free_adr)) mc.LEA(edx, addr_add(eax, imm(size))) mc.CMP(edx, heap(nursery_top_adr)) - mc.JNA(rel8(mc.tell())) + mc.JNA(rel8_patched_later) jmp_adr = mc.get_relative_pos() # See comments in _build_malloc_fixedsize_slowpath for the Modified: pypy/trunk/pypy/jit/backend/x86/ri386.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/ri386.py (original) +++ pypy/trunk/pypy/jit/backend/x86/ri386.py Fri Mar 19 10:47:20 2010 @@ -207,19 +207,22 @@ class MODRM8(MODRM): width = 1 -class REL(OPERAND): +class REL32(OPERAND): + width = 4 def __init__(self, absolute_target): self.absolute_target = absolute_target def assembler(self): return '%d' % (self.absolute_target,) -class REL32(REL): - width = 4 - -class REL8(REL): - def assembler(self): - return '.+%d' % (self.absolute_target,) +class REL8(OPERAND): width = 1 + def __init__(self, relative_target): # NB. a *relative* target + assert single_byte(relative_target) + self.relative_target = relative_target + def assembler(self): + # a bit of a hack: only works if a nextlabel is attached + nextlabel = getattr(self, 'nextlabel', '?') + return '%s+%d' % (nextlabel, self.relative_target,) class MISSING(OPERAND): def __repr__(self): @@ -413,6 +416,7 @@ constlistofchars._annspecialcase_ = 'specialize:memo' missing = MISSING() +rel8_patched_later = rel8(0) # __________________________________________________________ # Abstract base class, with methods like NOP(), ADD(x, y), etc. Modified: pypy/trunk/pypy/jit/backend/x86/ri386setup.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/ri386setup.py (original) +++ pypy/trunk/pypy/jit/backend/x86/ri386setup.py Fri Mar 19 10:47:20 2010 @@ -115,9 +115,7 @@ % (self.op,)) lines.append('builder.write(packimm32(offset))') elif self.width == 'b': - lines.append('offset = arg%d.absolute_target - (builder.tell()+2)' - % (self.op,)) - lines.append('assert offset < 127') + lines.append('offset = arg%d.relative_target' % (self.op,)) lines.append('builder.write(packimm8(offset))') else: raise ValueError("Invalid width %s" % (self.width,)) Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ri386.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_ri386.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_ri386.py Fri Mar 19 10:47:20 2010 @@ -77,6 +77,9 @@ #yield check, '\xDD\x44\x24\x04', 'FLD', mem(esp, 4) # fadd #yield check, '\xDC\x44\x24\x08', 'FADD', mem(esp, 8) + # JB +5 + yield check, '\x72\x05', 'JB', rel8(+5) + ##def test_conditional(): ## """Compare the encoding for the instructions JE, JAE, JC etc., Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Fri Mar 19 10:47:20 2010 @@ -4,8 +4,7 @@ from pypy.jit.backend.x86.ri386setup import all_instructions from pypy.tool.udir import udir -INPUTNAME = str(udir.join('checkfile.s')) -FILENAME = str(udir.join('checkfile.tmp')) +FILEBASE = str(udir.join('checkfile')) BEGIN_TAG = '<<>>' END_TAG = '<<>>' @@ -57,7 +56,7 @@ return map(i386.imm8, v) def rel8_tests(): - v = [-1,0,1] + [random.randrange(-123, 123) for i in range(COUNT1)] + v = [-128,-1,0,1,127] + [random.randrange(-127, 127) for i in range(COUNT1)] return map(i386.rel8, v) def imm16_tests(): @@ -138,7 +137,7 @@ instrname = instr.as_alias or instrname labelcount = 0 oplist = [] - g = open(INPUTNAME, 'w') + g = open(FILEBASE + instrname + '.s', 'w') g.write('\x09.string "%s"\n' % BEGIN_TAG) for args in args_lists: suffix = "" @@ -154,7 +153,9 @@ suffix = "" if args[-1][0] in (i386.REL8,i386.REL32): labelcount += 1 - following = "\nL%d:" % labelcount + labelname = "L%d" % labelcount + following = "\n%s:" % labelname + args[-1][1].nextlabel = labelname elif args[-1][0] in (i386.IMM8,i386.IMM32): args = list(args) args[-1] = ("%d", args[-1][1]) # no '$' sign @@ -173,9 +174,10 @@ oplist.append(op) g.write('\x09.string "%s"\n' % END_TAG) g.close() - os.system('as "%s" -o "%s"' % (INPUTNAME, FILENAME)) + os.system('as "%s.s" -o "%s.tmp"' % (FILEBASE + instrname, + FILEBASE + instrname)) try: - f = open(FILENAME, 'rb') + f = open(FILEBASE + instrname + '.tmp', 'rb') except IOError: raise Exception("Assembler error") data = f.read() @@ -260,9 +262,6 @@ self.op = op self.instrindex = self.index - def tell(self): - return 0 - def write(self, listofchars): data = ''.join(listofchars) end = self.index+len(data) From arigo at codespeak.net Fri Mar 19 10:54:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Mar 2010 10:54:42 +0100 (CET) Subject: [pypy-svn] r72406 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100319095442.ADC91282BDB@codespeak.net> Author: arigo Date: Fri Mar 19 10:54:40 2010 New Revision: 72406 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/runner.py Log: Rename 'faildescr._x86_adr_jump_offset' into '_x86_adr_jump_offset1' to avoid some random code that would still use it and not know that it must also consider '_x86_adr_jump_offset2'. Found exactly such a place in runner.py (although it's only about silencing warnings). Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 10:54:40 2010 @@ -296,8 +296,7 @@ def patch_jump_for_descr(self, faildescr, adr_new_target): - adr_jump_offset = faildescr._x86_adr_jump_offset - self.patch_jump(faildescr._x86_adr_jump_offset, adr_new_target) + self.patch_jump(faildescr._x86_adr_jump_offset1, adr_new_target) if faildescr._x86_adr_jump_offset2: self.patch_jump(faildescr._x86_adr_jump_offset2, adr_new_target) @@ -498,8 +497,8 @@ dispatch_opnum = op.opnum t = genop_guard_list[dispatch_opnum](self, op, guard_op, failaddr, arglocs, resloc) - adr_jump_offset, adr_jump_offset2 = t - faildescr._x86_adr_jump_offset = adr_jump_offset + adr_jump_offset1, adr_jump_offset2 = t + faildescr._x86_adr_jump_offset1 = adr_jump_offset1 faildescr._x86_adr_jump_offset2 = adr_jump_offset2 def regalloc_perform_guard(self, guard_op, faillocs, arglocs, resloc, Modified: pypy/trunk/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/runner.py Fri Mar 19 10:54:40 2010 @@ -150,10 +150,10 @@ history.LoopToken._x86_bootstrap_code = 0 history.LoopToken._x86_direct_bootstrap_code = 0 history.LoopToken._x86_failure_recovery_bytecode = 0 -history.LoopToken._x86_adr_jump_offset = 0 history.LoopToken._x86_loop_code = 0 history.LoopToken._x86_current_depths = (0, 0) compile._DoneWithThisFrameDescr._x86_current_depths = (0, 0) compile._DoneWithThisFrameDescr._x86_failure_recovery_bytecode = 0 -compile._DoneWithThisFrameDescr._x86_adr_jump_offset = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset1 = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset2 = 0 From arigo at codespeak.net Fri Mar 19 12:11:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Mar 2010 12:11:50 +0100 (CET) Subject: [pypy-svn] r72407 - pypy/trunk/pypy/rpython/module Message-ID: <20100319111150.7B842282BDB@codespeak.net> Author: arigo Date: Fri Mar 19 12:11:48 2010 New Revision: 72407 Modified: pypy/trunk/pypy/rpython/module/ll_os.py Log: Fix this: it is called typically with the result of GetLastError(), which is a DWORD (i.e. an unsigned integer). Modified: pypy/trunk/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_os.py (original) +++ pypy/trunk/pypy/rpython/module/ll_os.py Fri Mar 19 12:11:48 2010 @@ -1544,7 +1544,7 @@ @registering(rwin32.FormatError) def register_rwin32_FormatError(self): - return extdef([int], str, + return extdef([rwin32.DWORD], str, "rwin32_FormatError", llimpl=rwin32.llimpl_FormatError, ooimpl=rwin32.fake_FormatError) From afa at codespeak.net Fri Mar 19 13:07:09 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 13:07:09 +0100 (CET) Subject: [pypy-svn] r72408 - pypy/branch/kill-python-h/pypy/rlib Message-ID: <20100319120709.212CB282BDB@codespeak.net> Author: afa Date: Fri Mar 19 13:07:07 2010 New Revision: 72408 Removed: pypy/branch/kill-python-h/pypy/rlib/getaddrinfo.py pypy/branch/kill-python-h/pypy/rlib/getnameinfo.py Modified: pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py pypy/branch/kill-python-h/pypy/rlib/rsocket.py Log: At least since Visual Studio 8, getnameinfo() and getaddrinfo() are available. Drop compatibility code for older compilers. Also use rwin32.FormatError() instead of the hard-coded messages list. Modified: pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py Fri Mar 19 13:07:07 2010 @@ -448,13 +448,12 @@ socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t], rffi.INT) -if not WIN32: - getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP, - addrinfo_ptr, - lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT) - freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void) - getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, - size_t, CCHARP, size_t, rffi.INT], rffi.INT) +getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP, + addrinfo_ptr, + lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT) +freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void) +getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, + size_t, CCHARP, size_t, rffi.INT], rffi.INT) htonl = external('htonl', [rffi.UINT], rffi.UINT) htons = external('htons', [rffi.USHORT], rffi.USHORT) @@ -563,78 +562,14 @@ WSAGetLastError = external('WSAGetLastError', [], rffi.INT) geterrno = WSAGetLastError - - import errno - WIN32_ERROR_MESSAGES = { - errno.WSAEINTR: "Interrupted system call", - errno.WSAEBADF: "Bad file descriptor", - errno.WSAEACCES: "Permission denied", - errno.WSAEFAULT: "Bad address", - errno.WSAEINVAL: "Invalid argument", - errno.WSAEMFILE: "Too many open files", - errno.WSAEWOULDBLOCK: - "The socket operation could not complete without blocking", - errno.WSAEINPROGRESS: "Operation now in progress", - errno.WSAEALREADY: "Operation already in progress", - errno.WSAENOTSOCK: "Socket operation on non-socket", - errno.WSAEDESTADDRREQ: "Destination address required", - errno.WSAEMSGSIZE: "Message too long", - errno.WSAEPROTOTYPE: "Protocol wrong type for socket", - errno.WSAENOPROTOOPT: "Protocol not available", - errno.WSAEPROTONOSUPPORT: "Protocol not supported", - errno.WSAESOCKTNOSUPPORT: "Socket type not supported", - errno.WSAEOPNOTSUPP: "Operation not supported", - errno.WSAEPFNOSUPPORT: "Protocol family not supported", - errno.WSAEAFNOSUPPORT: "Address family not supported", - errno.WSAEADDRINUSE: "Address already in use", - errno.WSAEADDRNOTAVAIL: "Can't assign requested address", - errno.WSAENETDOWN: "Network is down", - errno.WSAENETUNREACH: "Network is unreachable", - errno.WSAENETRESET: "Network dropped connection on reset", - errno.WSAECONNABORTED: "Software caused connection abort", - errno.WSAECONNRESET: "Connection reset by peer", - errno.WSAENOBUFS: "No buffer space available", - errno.WSAEISCONN: "Socket is already connected", - errno.WSAENOTCONN: "Socket is not connected", - errno.WSAESHUTDOWN: "Can't send after socket shutdown", - errno.WSAETOOMANYREFS: "Too many references: can't splice", - errno.WSAETIMEDOUT: "Operation timed out", - errno.WSAECONNREFUSED: "Connection refused", - errno.WSAELOOP: "Too many levels of symbolic links", - errno.WSAENAMETOOLONG: "File name too long", - errno.WSAEHOSTDOWN: "Host is down", - errno.WSAEHOSTUNREACH: "No route to host", - errno.WSAENOTEMPTY: "Directory not empty", - errno.WSAEPROCLIM: "Too many processes", - errno.WSAEUSERS: "Too many users", - errno.WSAEDQUOT: "Disc quota exceeded", - errno.WSAESTALE: "Stale NFS file handle", - errno.WSAEREMOTE: "Too many levels of remote in path", - errno.WSASYSNOTREADY: "Network subsystem is unvailable", - errno.WSAVERNOTSUPPORTED: "WinSock version is not supported", - errno.WSANOTINITIALISED: "Successful WSAStartup() not yet performed", - errno.WSAEDISCON: "Graceful shutdown in progress", - - # Resolver errors - # XXX Not exported by errno. Replace by the values in winsock.h - # errno.WSAHOST_NOT_FOUND: "No such host is known", - # errno.WSATRY_AGAIN: "Host not found, or server failed", - # errno.WSANO_RECOVERY: "Unexpected server error encountered", - # errno.WSANO_DATA: "Valid name without requested data", - # errno.WSANO_ADDRESS: "No address, look for MX record", - - # select() errors - WSA_IO_PENDING: "WSA_IO_PENDING", - WSA_IO_INCOMPLETE: "WSA_IO_INCOMPLETE", - WSA_INVALID_HANDLE: "WSA_INVALID_HANDLE", - WSA_INVALID_PARAMETER: "WSA_INVALID_PARAMETER", - WSA_NOT_ENOUGH_MEMORY: "WSA_NOT_ENOUGH_MEMORY", - WSA_OPERATION_ABORTED: "WSA_OPERATION_ABORTED", - } - assert len(WIN32_ERROR_MESSAGES) == 53 # detect duplicates + from pypy.rlib import rwin32 def socket_strerror_str(errno): - return WIN32_ERROR_MESSAGES.get(errno, "winsock error %d" % errno) + return rwin32.FormatError(errno) + def gai_strerror_str(errno): + return rwin32.FormatError(errno) else: socket_strerror_str = os.strerror + def gai_strerror_str(errno): + return rffi.charp2str(gai_strerror(self.errno)) Modified: pypy/branch/kill-python-h/pypy/rlib/rsocket.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/rsocket.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/rsocket.py Fri Mar 19 13:07:07 2010 @@ -1040,8 +1040,7 @@ class GAIError(SocketErrorWithErrno): applevelerrcls = 'gaierror' def get_msg(self): - # this method may be patched below - return rffi.charp2str(_c.gai_strerror(self.errno)) + return _c.gai_strerror_str(self.errno) class HSocketError(SocketError): applevelerrcls = 'herror' @@ -1334,17 +1333,3 @@ if timeout < 0.0: timeout = -1.0 defaults.timeout = timeout - -# _______________________________________________________________ -# -# Patch module, for platforms without getaddrinfo / getnameinfo -# - -if not getattr(_c, 'getaddrinfo', None): - from pypy.rlib.getaddrinfo import getaddrinfo - from pypy.rlib.getaddrinfo import GAIError_getmsg - GAIError.get_msg = GAIError_getmsg - -if not getattr(_c, 'getnameinfo', None): - from pypy.rlib.getnameinfo import getnameinfo - from pypy.rlib.getnameinfo import NI_NUMERICHOST, NI_NUMERICSERV From afa at codespeak.net Fri Mar 19 13:09:05 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 13:09:05 +0100 (CET) Subject: [pypy-svn] r72409 - pypy/branch/kill-python-h/pypy/translator/c/gcc Message-ID: <20100319120905.E9D24282BDB@codespeak.net> Author: afa Date: Fri Mar 19 13:09:04 2010 New Revision: 72409 Modified: pypy/branch/kill-python-h/pypy/translator/c/gcc/trackgcroot.py Log: When targeting windows2000, ws2tcpip.h generates a compatibility function for getaddrinfo(). trackgcroot.py needs to support the definition of inline STDCALL functions. Modified: pypy/branch/kill-python-h/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/kill-python-h/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/kill-python-h/pypy/translator/c/gcc/trackgcroot.py Fri Mar 19 13:09:04 2010 @@ -331,6 +331,11 @@ label = label2 if label is None: k = call.lineno + if self.format == 'msvc': + # Some header files (ws2tcpip.h) define STDCALL functions + funcname = self.funcname.split('@')[0] + else: + funcname = self.funcname while 1: label = '__gcmap_%s__%s_%d' % (self.filetag, self.funcname, k) if label not in self.labels: From fijal at codespeak.net Fri Mar 19 16:07:10 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 16:07:10 +0100 (CET) Subject: [pypy-svn] r72415 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100319150710.CD1CE282BDB@codespeak.net> Author: fijal Date: Fri Mar 19 16:07:09 2010 New Revision: 72415 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/runner.py Log: Use rel8 in places where dual address was used for faildescr. Kill dual addr for faildescr. Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Fri Mar 19 16:07:09 2010 @@ -294,13 +294,8 @@ return op.args[0]._get_str() return "" - def patch_jump_for_descr(self, faildescr, adr_new_target): - self.patch_jump(faildescr._x86_adr_jump_offset1, adr_new_target) - if faildescr._x86_adr_jump_offset2: - self.patch_jump(faildescr._x86_adr_jump_offset2, adr_new_target) - - def patch_jump(self, adr_jump_offset, adr_new_target): + adr_jump_offset = faildescr._x86_adr_jump_offset mc = codebuf.InMemoryCodeBuilder(adr_jump_offset, adr_jump_offset + 4) mc.write(packimm32(adr_new_target - adr_jump_offset - 4)) mc.valgrind_invalidated() @@ -495,11 +490,9 @@ dispatch_opnum = guard_opnum else: dispatch_opnum = op.opnum - t = genop_guard_list[dispatch_opnum](self, op, guard_op, failaddr, - arglocs, resloc) - adr_jump_offset1, adr_jump_offset2 = t - faildescr._x86_adr_jump_offset1 = adr_jump_offset1 - faildescr._x86_adr_jump_offset2 = adr_jump_offset2 + res = genop_guard_list[dispatch_opnum](self, op, guard_op, failaddr, + arglocs, resloc) + faildescr._x86_adr_jump_offset = res def regalloc_perform_guard(self, guard_op, faillocs, arglocs, resloc, current_depths): @@ -553,18 +546,18 @@ self.mc.CMP(arglocs[1], arglocs[0]) if guard_opnum == rop.GUARD_FALSE: name = 'J' + rev_cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + return self.implement_guard(addr, getattr(self.mc, name)) else: name = 'J' + false_rev_cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + return self.implement_guard(addr, getattr(self.mc, name)) else: self.mc.CMP(arglocs[0], arglocs[1]) if guard_opnum == rop.GUARD_FALSE: name = 'J' + cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + return self.implement_guard(addr, getattr(self.mc, name)) else: name = 'J' + false_cond - return self.implement_guard(addr, getattr(self.mc, name)), 0 + return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard def _cmpop_guard_float(cond, false_cond, need_jp): @@ -576,17 +569,17 @@ mc = self.mc._mc name = 'J' + cond if need_jp: - mc.JP(rel32(mc.tell() + 12)) + mc.JP(rel8(6)) getattr(mc, name)(rel32(addr)) - return mc.tell() - 4, 0 + return mc.tell() - 4 else: - name = 'J' + false_cond - addr1 = self.implement_guard(addr, getattr(self.mc, name)) if need_jp: - addr2 = self.implement_guard(addr, self.mc.JP) - else: - addr2 = 0 - return addr1, addr2 + mc = self.mc._mc + mc.JP(rel8(2)) + getattr(mc, 'J' + cond)(rel8(5)) + return self.implement_guard(addr, mc.JMP) + name = 'J' + false_cond + return self.implement_guard(addr, getattr(self.mc, name)) return genop_cmp_guard_float @specialize.arg(5) @@ -684,15 +677,15 @@ def genop_guard_float_ne(self, op, guard_op, addr, arglocs, result_loc): guard_opnum = guard_op.opnum self.mc.UCOMISD(arglocs[0], arglocs[1]) + mc = self.mc._mc if guard_opnum == rop.GUARD_TRUE: - mc = self.mc._mc - mc.JP(rel32(mc.tell() + 12)) + mc.JP(rel8(6)) mc.JE(rel32(addr)) - return mc.tell() - 4, 0 + return mc.tell() - 4 else: - addr1 = self.implement_guard(addr, self.mc.JNE) - addr2 = self.implement_guard(addr, self.mc.JP) - return addr1, addr2 + mc.JP(rel8(2)) + mc.JE(rel8(5)) + return self.implement_guard(addr, mc.JMP) def genop_float_neg(self, op, arglocs, resloc): # Following what gcc does: res = x ^ 0x8000000000000000 @@ -707,15 +700,15 @@ loc0, loc1 = arglocs self.mc.XORPD(loc0, loc0) self.mc.UCOMISD(loc0, loc1) + mc = self.mc._mc if guard_opnum == rop.GUARD_TRUE: - mc = self.mc._mc - mc.JP(rel32(mc.tell() + 2*6)) + mc.JP(rel8(6)) mc.JZ(rel32(addr)) - return mc.tell() - 4, 0 + return mc.tell() - 4 else: - addr1 = self.implement_guard(addr, self.mc.JNZ) - addr2 = self.implement_guard(addr, self.mc.JP) - return addr1, addr2 + mc.JP(rel8(2)) + mc.JZ(rel8(5)) + return self.implement_guard(addr, mc.JMP) def genop_float_is_true(self, op, arglocs, resloc): loc0, loc1 = arglocs @@ -756,9 +749,9 @@ guard_opnum = guard_op.opnum self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: - return self.implement_guard(addr, self.mc.JZ), 0 + return self.implement_guard(addr, self.mc.JZ) else: - return self.implement_guard(addr, self.mc.JNZ), 0 + return self.implement_guard(addr, self.mc.JNZ) def genop_int_is_true(self, op, arglocs, resloc): self.mc.CMP(arglocs[0], imm8(0)) @@ -770,9 +763,9 @@ guard_opnum = guard_op.opnum self.mc.CMP(arglocs[0], imm8(0)) if guard_opnum == rop.GUARD_TRUE: - return self.implement_guard(addr, self.mc.JNZ), 0 + return self.implement_guard(addr, self.mc.JNZ) else: - return self.implement_guard(addr, self.mc.JZ), 0 + return self.implement_guard(addr, self.mc.JZ) def genop_bool_not(self, op, arglocs, resloc): self.mc.XOR(arglocs[0], imm8(1)) @@ -955,13 +948,13 @@ def genop_guard_guard_true(self, ign_1, guard_op, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) - return self.implement_guard(addr, self.mc.JZ), 0 + return self.implement_guard(addr, self.mc.JZ) genop_guard_guard_nonnull = genop_guard_guard_true def genop_guard_guard_no_exception(self, ign_1, guard_op, addr, locs, ign_2): self.mc.CMP(heap(self.cpu.pos_exception()), imm(0)) - return self.implement_guard(addr, self.mc.JNZ), 0 + return self.implement_guard(addr, self.mc.JNZ) def genop_guard_guard_exception(self, ign_1, guard_op, addr, locs, resloc): @@ -974,20 +967,20 @@ self.mc.MOV(resloc, heap(self.cpu.pos_exc_value())) self.mc.MOV(heap(self.cpu.pos_exception()), imm(0)) self.mc.MOV(heap(self.cpu.pos_exc_value()), imm(0)) - return addr, 0 + return addr def genop_guard_guard_no_overflow(self, ign_1, guard_op, addr, locs, resloc): - return self.implement_guard(addr, self.mc.JO), 0 + return self.implement_guard(addr, self.mc.JO) def genop_guard_guard_overflow(self, ign_1, guard_op, addr, locs, resloc): - return self.implement_guard(addr, self.mc.JNO), 0 + return self.implement_guard(addr, self.mc.JNO) def genop_guard_guard_false(self, ign_1, guard_op, addr, locs, ign_2): loc = locs[0] self.mc.TEST(loc, loc) - return self.implement_guard(addr, self.mc.JNZ), 0 + return self.implement_guard(addr, self.mc.JNZ) genop_guard_guard_isnull = genop_guard_guard_false def genop_guard_guard_value(self, ign_1, guard_op, addr, locs, ign_2): @@ -996,7 +989,7 @@ self.mc.UCOMISD(locs[0], locs[1]) else: self.mc.CMP(locs[0], locs[1]) - return self.implement_guard(addr, self.mc.JNE), 0 + return self.implement_guard(addr, self.mc.JNE) def _cmp_guard_class(self, mc, locs): offset = self.cpu.vtable_offset @@ -1022,7 +1015,7 @@ mc = self._start_block() self._cmp_guard_class(mc, locs) self._stop_block() - return self.implement_guard(addr, self.mc.JNE), 0 + return self.implement_guard(addr, self.mc.JNE) def genop_guard_guard_nonnull_class(self, ign_1, guard_op, addr, locs, ign_2): @@ -1037,7 +1030,7 @@ mc.overwrite(jb_location-1, [chr(offset)]) self._stop_block() # - return self.implement_guard(addr, self.mc.JNE), 0 + return self.implement_guard(addr, self.mc.JNE) def implement_guard_recovery(self, guard_opnum, faildescr, failargs, fail_locs): @@ -1413,7 +1406,7 @@ self.mc.MOV(mem(ebp, FORCE_INDEX_OFS), imm(fail_index)) self.genop_call(op, arglocs, result_loc) self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) - return self.implement_guard(addr, self.mc.JL), 0 + return self.implement_guard(addr, self.mc.JL) def genop_guard_call_assembler(self, op, guard_op, addr, arglocs, result_loc): @@ -1446,7 +1439,7 @@ else: assert result_loc is eax or result_loc is None self.mc.CMP(mem(ebp, FORCE_INDEX_OFS), imm(0)) - return self.implement_guard(addr, self.mc.JL), 0 + return self.implement_guard(addr, self.mc.JL) def genop_discard_cond_call_gc_wb(self, op, arglocs): # use 'mc._mc' directly instead of 'mc', to avoid Modified: pypy/trunk/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/runner.py Fri Mar 19 16:07:09 2010 @@ -155,5 +155,5 @@ compile._DoneWithThisFrameDescr._x86_current_depths = (0, 0) compile._DoneWithThisFrameDescr._x86_failure_recovery_bytecode = 0 -compile._DoneWithThisFrameDescr._x86_adr_jump_offset1 = 0 -compile._DoneWithThisFrameDescr._x86_adr_jump_offset2 = 0 +compile._DoneWithThisFrameDescr._x86_adr_jump_offset = 0 + From afa at codespeak.net Fri Mar 19 19:03:00 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 19:03:00 +0100 (CET) Subject: [pypy-svn] r72419 - in pypy/trunk/pypy: doc/config module/cpyext module/cpyext/include module/cpyext/test Message-ID: <20100319180300.27196282BDB@codespeak.net> Author: afa Date: Fri Mar 19 19:02:58 2010 New Revision: 72419 Added: pypy/trunk/pypy/doc/config/objspace.usemodules.cpyext.txt (contents, props changed) pypy/trunk/pypy/module/cpyext/ (props changed) pypy/trunk/pypy/module/cpyext/__init__.py (contents, props changed) pypy/trunk/pypy/module/cpyext/api.py (contents, props changed) pypy/trunk/pypy/module/cpyext/include/ pypy/trunk/pypy/module/cpyext/include/Python.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/modsupport.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/pythonrun.h (contents, props changed) pypy/trunk/pypy/module/cpyext/modsupport.py (contents, props changed) pypy/trunk/pypy/module/cpyext/pythonrun.py (contents, props changed) pypy/trunk/pypy/module/cpyext/test/ (props changed) pypy/trunk/pypy/module/cpyext/test/autopath.py - copied unchanged from r72407, pypy/branch/kill-python-h/pypy/module/sys/test/autopath.py pypy/trunk/pypy/module/cpyext/test/test_cpytext.py (contents, props changed) Log: crazy: try to import CPython modules into pypy. So far, only the test framework is done, plus 2 functions Added: pypy/trunk/pypy/doc/config/objspace.usemodules.cpyext.txt ============================================================================== --- (empty file) +++ pypy/trunk/pypy/doc/config/objspace.usemodules.cpyext.txt Fri Mar 19 19:02:58 2010 @@ -0,0 +1 @@ +Use (experimental) cpyext module, that tries to load and run CPython extension modules Added: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/__init__.py Fri Mar 19 19:02:58 2010 @@ -0,0 +1,33 @@ +from pypy.interpreter.mixedmodule import MixedModule +from pypy.rlib.objectmodel import we_are_translated +import pypy.module.cpyext.api + +class State: + def __init__(self, space): + if not we_are_translated(): + self.api_lib = str(api.build_bridge(space)) + else: + XXX # build an import library when translating pypy. + +class Module(MixedModule): + interpleveldefs = { + } + + appleveldefs = { + } + + def setup_after_space_initialization(self): + """NOT_RPYTHON""" + state = self.space.fromcache(State) + + def startup(self, space): + state = space.fromcache(State) + space.setattr(space.wrap(self), + space.wrap('api_lib'), + space.wrap(state.api_lib)) + +# import these modules to register api functions by side-effect +import pypy.module.cpyext.modsupport +import pypy.module.cpyext.pythonrun + + Added: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/api.py Fri Mar 19 19:02:58 2010 @@ -0,0 +1,95 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.rpython.lltypesystem import ll2ctypes +from pypy.rpython.annlowlevel import llhelper +from pypy.translator.c.database import LowLevelDatabase +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.translator import platform + +class ApiFunction: + def __init__(self, argtypes, restype, callable): + self.argtypes = argtypes + self.restype = restype + self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) + self.callable = callable + +def cpython_api(argtypes, restype): + def decorate(func): + FUNCTIONS[func.func_name] = ApiFunction(argtypes, restype, func) + return func + return decorate + +def cpython_struct(name): + struct = rffi.CStruct('PyMethodDef') + TYPES[name] = struct + return struct + +FUNCTIONS = {} +TYPES = {} + +#_____________________________________________________ +# Build the bridge DLL, Allow extension DLLs to call +# back into Pypy space functions +def build_bridge(space): + db = LowLevelDatabase() + + structindex = {} + + # Structure declaration code + members = [] + for name, func in FUNCTIONS.iteritems(): + cdecl = db.gettype(func.functype) + members.append(cdecl.replace('@', name) + ';') + structindex[name] = len(structindex) + structmembers = '\n'.join(members) + struct_declaration_code = """\ + struct PyPyAPI { + %(members)s + } _pypyAPI; + struct PyPyAPI* pypyAPI = &_pypyAPI; + """ % dict(members=structmembers) + + # implement function callbacks + functions = [] + for name, func in FUNCTIONS.iteritems(): + restype = db.gettype(func.restype).replace('@', '') + args = [] + for i, argtype in enumerate(func.argtypes): + arg = db.gettype(argtype) + arg = arg.replace('@', 'arg%d' % (i,)) + args.append(arg) + args = ', '.join(args) + callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) + header = "%s %s(%s)" % (restype, name, args) + body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) + functions.append('%s\n%s\n' % (header, body)) + + code = struct_declaration_code + '\n' + '\n'.join(functions) + + # Build code and get pointer to the structure + eci = ExternalCompilationInfo( + separate_module_sources=[code], + export_symbols=['pypyAPI'] + list(FUNCTIONS), + ) + eci = eci.convert_sources_to_files() + modulename = platform.platform.compile( + [], eci, + standalone=False) + + # load the bridge, and init structure + import ctypes + bridge = ctypes.CDLL(str(modulename)) + pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') + + def make_wrapper(callable): + def wrapper(*args): + return callable(space, *args) + return wrapper + + # implement structure initialization code + for name, func in FUNCTIONS.iteritems(): + pypyAPI[structindex[name]] = ctypes.cast( + ll2ctypes.lltype2ctypes(llhelper(func.functype, make_wrapper(func.callable))), + ctypes.c_void_p) + + return modulename.new(ext='') + Added: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Fri Mar 19 19:02:58 2010 @@ -0,0 +1,8 @@ +#ifndef Py_PYTHON_H +#define Py_PYTHON_H + +#include +#include "modsupport.h" +#include "pythonrun.h" + +#endif Added: pypy/trunk/pypy/module/cpyext/include/modsupport.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/modsupport.h Fri Mar 19 19:02:58 2010 @@ -0,0 +1,2 @@ +typedef struct PyMethodDef PyMethodDef; +void Py_InitModule(const char* name, PyMethodDef* methods); Added: pypy/trunk/pypy/module/cpyext/include/pythonrun.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/pythonrun.h Fri Mar 19 19:02:58 2010 @@ -0,0 +1,14 @@ +/* Interfaces to parse and execute pieces of python code */ + +#ifndef Py_PYTHONRUN_H +#define Py_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +int Py_IsInitialized(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHONRUN_H */ Added: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Fri Mar 19 19:02:58 2010 @@ -0,0 +1,19 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, cpython_struct +from pypy.interpreter.module import Module + +PyMethodDef = cpython_struct('PyMethodDef') + +def PyImport_AddModule(space, name): + w_name = space.wrap(name) + w_mod = space.wrap(Module(space, w_name)) + + w_modules = space.sys.get('modules') + space.setitem(w_modules, w_name, w_mod) + return w_mod + + at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) +def Py_InitModule(space, name, methods): + name = rffi.charp2str(name) + PyImport_AddModule(space, name) + assert not methods # For the moment Added: pypy/trunk/pypy/module/cpyext/pythonrun.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/pythonrun.py Fri Mar 19 19:02:58 2010 @@ -0,0 +1,6 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api + + at cpython_api([], lltype.Signed) +def Py_IsInitialized(space): + return 1 Added: pypy/trunk/pypy/module/cpyext/test/test_cpytext.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/test_cpytext.py Fri Mar 19 19:02:58 2010 @@ -0,0 +1,67 @@ +import py, autopath + +from pypy.conftest import gettestobjspace +from pypy.interpreter.error import OperationError +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.translator import platform +from pypy.module.cpyext import api + +class TestApi(): + def test_signature(self): + assert 'Py_InitModule' in api.FUNCTIONS + assert api.FUNCTIONS['Py_InitModule'].argtypes == [ + rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] + assert api.FUNCTIONS['Py_InitModule'].restype == lltype.Void + +def compile_module(name, code, libraries=()): + include_dir = py.path.local(autopath.pypydir).join( + 'module', 'cpyext', 'include') + eci = ExternalCompilationInfo( + separate_module_sources=[code], + export_symbols=['init%s' % (name,)], + include_dirs=[include_dir], + libraries=libraries, + ) + eci = eci.convert_sources_to_files() + soname = platform.platform.compile( + [], eci, + standalone=False) + return str(soname) + +class AppTestCpythonExtension: + def setup_class(cls): + cls.api_library = api.build_bridge(cls.space) + + def import_module(self, name, init, body=''): + code = """ + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + mod = compile_module(name, code, libraries=[self.api_library]) + import ctypes + initfunc = ctypes.CDLL(mod)['init%s' % (name,)] + initfunc() + + def setup_method(self, func): + self.w_import_module = self.space.wrap(self.import_module) + + def teardown_method(self, func): + try: + self.space.delitem(self.space.sys.get('modules'), + self.space.wrap('foo')) + except OperationError: + pass + + def test_createmodule(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", NULL); + """ + self.import_module(name='foo', init=init) + assert 'foo' in sys.modules From afa at codespeak.net Fri Mar 19 19:03:44 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 19:03:44 +0100 (CET) Subject: [pypy-svn] r72420 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100319180344.DEBB4282BDB@codespeak.net> Author: afa Date: Fri Mar 19 19:03:43 2010 New Revision: 72420 Added: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py - copied unchanged from r72419, pypy/trunk/pypy/module/cpyext/test/test_cpytext.py Removed: pypy/trunk/pypy/module/cpyext/test/test_cpytext.py Log: Rename test file From getxsick at codespeak.net Fri Mar 19 19:18:32 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 19 Mar 2010 19:18:32 +0100 (CET) Subject: [pypy-svn] r72421 - pypy/build/ubuntu/debian Message-ID: <20100319181832.21FCD282BDB@codespeak.net> Author: getxsick Date: Fri Mar 19 19:18:30 2010 New Revision: 72421 Modified: pypy/build/ubuntu/debian/control Log: Add missing build-depends Modified: pypy/build/ubuntu/debian/control ============================================================================== --- pypy/build/ubuntu/debian/control (original) +++ pypy/build/ubuntu/debian/control Fri Mar 19 19:18:30 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev Standards-Version: 3.8.0 Homepage: http://pypy.org From fijal at codespeak.net Fri Mar 19 19:30:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 19:30:59 +0100 (CET) Subject: [pypy-svn] r72422 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100319183059.023AF282BDB@codespeak.net> Author: fijal Date: Fri Mar 19 19:30:58 2010 New Revision: 72422 Added: pypy/extradoc/talk/oopsla2010/paper3.txt (contents, props changed) Log: Another approach to write introduction Added: pypy/extradoc/talk/oopsla2010/paper3.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/oopsla2010/paper3.txt Fri Mar 19 19:30:58 2010 @@ -0,0 +1,50 @@ +Abstract +======== + +XXX + +Introduction +============ + +Python language presents a serious challenge for optimizations. The main +complexity comes from the dynamism of Python (where you can overload virtually +any operation to have effects unknown until runtime) as well as frame +introspection capabilities achievable from within language. We implemented +a flexible just in time compiler generation (XXX cite) as a first step +to overcome problems presented by Python. In our approach, we automatically +generate the just in time compiler from the interpreter specification written +in a high level language (RPython - a static subset of Python). This language +can also be directly run or, by compilation to lower level language such as C, +run efficiently. + +The idea of frame introspection is very useful for debugging, especially when +building custom debuggers or traceback representation. An example of such +idea is found with web frameworks written in python - they usually try to +present more information than classic traceback representation. + +XXX example of django traceback + +In this paper we present the way we deal with frames in order to completely +(or mostly) avoid costs associated with them. Our approach is giving +us serious (XXX how serious) performance benefit on top of just in time +compiler without the frame optimizations. + +The performance evaluation of our approach is based on a fact that if +programmer doesn't use frame introspection, he's not interested in paying +extra penalty for it. The performance of the introspection capabilities +doesn't matter in practice, since by far the most common use case is debugging. +At least in case of python, there is a requirement however, that debugging +information is present and retrievable at any point of execution - there +can't be a runtime option known prior to running the program if debugging +will be used or not. + +The idea of avoiding frame objects, while still being able to create them +if need arises is nothing new. It was tackled by (XXX smalltalk) and +(XXX hotspot) for years. The novelty of our approach is that we only need +a few hints in our interpreter (a couple lines of code, about 10) to instruct +jit generator to create frame synchronization code. This allows the same +techniques to be applied to any interpreter specified in description +language (RPython). Indeed, in order to present gains of our approach, +we created a tiny language and wrote interpreter for it in RPython to showcase +benefits of our that can also be applied on a large scale. + From afa at codespeak.net Fri Mar 19 20:20:23 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 20:20:23 +0100 (CET) Subject: [pypy-svn] r72423 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100319192023.190A1282BDB@codespeak.net> Author: afa Date: Fri Mar 19 20:20:21 2010 New Revision: 72423 Added: pypy/trunk/pypy/module/cpyext/floatobject.py (contents, props changed) pypy/trunk/pypy/module/cpyext/include/floatobject.h pypy/trunk/pypy/module/cpyext/include/methodobject.h Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/modsupport.h pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Start to iterate over the PyMethodDef array, this needed some support for "configure". Next step: really expose the function object. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Fri Mar 19 20:20:21 2010 @@ -27,7 +27,8 @@ space.wrap(state.api_lib)) # import these modules to register api functions by side-effect +import pypy.module.cpyext.floatobject import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun - - +from pypy.module.cpyext import api +api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Fri Mar 19 20:20:21 2010 @@ -1,10 +1,22 @@ from pypy.rpython.lltypesystem import rffi, lltype +from pypy.rpython.tool import rffi_platform from pypy.rpython.lltypesystem import ll2ctypes from pypy.rpython.annlowlevel import llhelper from pypy.translator.c.database import LowLevelDatabase from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator import platform +import py, autopath + +include_dir = py.path.local(autopath.pypydir).join( + 'module', 'cpyext', 'include') + +class CConfig: + _compilation_info_ = ExternalCompilationInfo( + include_dirs=[include_dir], + includes=['Python.h'] + ) + class ApiFunction: def __init__(self, argtypes, restype, callable): self.argtypes = argtypes @@ -18,14 +30,21 @@ return func return decorate -def cpython_struct(name): - struct = rffi.CStruct('PyMethodDef') - TYPES[name] = struct - return struct +def cpython_struct(name, fields): + setattr(CConfig, name, rffi_platform.Struct(name, fields)) + forward = lltype.ForwardReference() + TYPES[name] = forward + return forward FUNCTIONS = {} TYPES = {} +PyObject = cpython_struct('PyObject', []) + +def configure(): + for name, TYPE in rffi_platform.configure(CConfig).iteritems(): + TYPES[name].become(TYPE) + #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions @@ -42,6 +61,7 @@ structindex[name] = len(structindex) structmembers = '\n'.join(members) struct_declaration_code = """\ + #include struct PyPyAPI { %(members)s } _pypyAPI; @@ -67,6 +87,7 @@ # Build code and get pointer to the structure eci = ExternalCompilationInfo( + include_dirs=[include_dir], separate_module_sources=[code], export_symbols=['pypyAPI'] + list(FUNCTIONS), ) Added: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Fri Mar 19 20:20:21 2010 @@ -0,0 +1,6 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject + + at cpython_api([lltype.Float], lltype.Ptr(PyObject)) +def PyFloat_FromDouble(space, value): + return space.wrap(value) Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Fri Mar 19 20:20:21 2010 @@ -1,7 +1,15 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H +typedef struct _object { + int __dummy; +} PyObject; + #include + +#include "floatobject.h" +#include "methodobject.h" + #include "modsupport.h" #include "pythonrun.h" Added: pypy/trunk/pypy/module/cpyext/include/floatobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/floatobject.h Fri Mar 19 20:20:21 2010 @@ -0,0 +1,16 @@ + +/* Float object interface */ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyObject* PyFloat_FromDouble(double); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ Added: pypy/trunk/pypy/module/cpyext/include/methodobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/methodobject.h Fri Mar 19 20:20:21 2010 @@ -0,0 +1,36 @@ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +/* Flag passed to newmethodobject */ +#define METH_OLDARGS 0x0000 +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ Modified: pypy/trunk/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/trunk/pypy/module/cpyext/include/modsupport.h Fri Mar 19 20:20:21 2010 @@ -1,2 +1,15 @@ -typedef struct PyMethodDef PyMethodDef; + +/* Module support interface */ + +#ifndef Py_MODSUPPORT_H +#define Py_MODSUPPORT_H +#ifdef __cplusplus +extern "C" { +#endif + void Py_InitModule(const char* name, PyMethodDef* methods); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODSUPPORT_H */ Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Fri Mar 19 20:20:21 2010 @@ -2,7 +2,10 @@ from pypy.module.cpyext.api import cpython_api, cpython_struct from pypy.interpreter.module import Module -PyMethodDef = cpython_struct('PyMethodDef') +PyMethodDef = cpython_struct( + 'PyMethodDef', + [('ml_name', rffi.CCHARP), + ]) def PyImport_AddModule(space, name): w_name = space.wrap(name) @@ -15,5 +18,15 @@ @cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) def Py_InitModule(space, name, methods): name = rffi.charp2str(name) - PyImport_AddModule(space, name) - assert not methods # For the moment + w_mod = PyImport_AddModule(space, name) + methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) + if methods: + i = 0 + while True: + method = methods[i] + if not method.c_ml_name: break + methodname = rffi.charp2str(method.c_ml_name) + space.setattr(w_mod, + space.wrap(methodname), + space.w_None) # XXX for the moment + i = i + 1 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Fri Mar 19 20:20:21 2010 @@ -46,6 +46,9 @@ import ctypes initfunc = ctypes.CDLL(mod)['init%s' % (name,)] initfunc() + return self.space.getitem( + self.space.sys.get('modules'), + self.space.wrap(name)) def setup_method(self, func): self.w_import_module = self.space.wrap(self.import_module) @@ -65,3 +68,24 @@ """ self.import_module(name='foo', init=init) assert 'foo' in sys.modules + + def test_export_function(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + PyObject* foo_pi(PyObject* self, PyObject *args) + { + return PyFloat_FromDouble(3.14); + } + static PyMethodDef methods[] = { + { "return_pi", foo_pi, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert 'foo' in sys.modules + assert 'return_pi' in dir(module) + assert module.return_pi is None # XXX for the moment From fijal at codespeak.net Fri Mar 19 20:36:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 19 Mar 2010 20:36:11 +0100 (CET) Subject: [pypy-svn] r72424 - pypy/build/bot2/pypybuildbot Message-ID: <20100319193611.349FD282BD4@codespeak.net> Author: fijal Date: Fri Mar 19 20:36:10 2010 New Revision: 72424 Modified: pypy/build/bot2/pypybuildbot/master.py Log: An approach to have nightly builds with correct mime type Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 19 20:36:10 2010 @@ -2,7 +2,7 @@ from buildbot.buildslave import BuildSlave from buildbot.status.html import WebStatus from buildbot.process.builder import Builder - +from twisted.web.static import DirectoryLister # I really wanted to pass logPath to Site from twisted.web.server import Site @@ -45,6 +45,8 @@ 'windows', 'mac', 'benchmark-run', 'other'])) +status.putChild('nightly', DirectoryLister(os.path.expanduser('~/nightly'), + defaultType='application/octet-stream')) pypybuilds = load('pypybuildbot.builds') From pedronis at codespeak.net Fri Mar 19 20:40:37 2010 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 19 Mar 2010 20:40:37 +0100 (CET) Subject: [pypy-svn] r72425 - pypy/build/bot2/pypybuildbot Message-ID: <20100319194037.D33AB282BD4@codespeak.net> Author: pedronis Date: Fri Mar 19 20:40:36 2010 New Revision: 72425 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Eh, use older twisted interface Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Fri Mar 19 20:40:36 2010 @@ -2,7 +2,7 @@ from buildbot.buildslave import BuildSlave from buildbot.status.html import WebStatus from buildbot.process.builder import Builder -from twisted.web.static import DirectoryLister +from twisted.web.woven.dirlist import DirectoryLister # I really wanted to pass logPath to Site from twisted.web.server import Site From getxsick at codespeak.net Fri Mar 19 21:07:14 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 19 Mar 2010 21:07:14 +0100 (CET) Subject: [pypy-svn] r72426 - pypy/build/ubuntu/debian Message-ID: <20100319200714.69BBD282BD4@codespeak.net> Author: getxsick Date: Fri Mar 19 21:06:07 2010 New Revision: 72426 Modified: pypy/build/ubuntu/debian/rules Log: update install-indep rules Modified: pypy/build/ubuntu/debian/rules ============================================================================== --- pypy/build/ubuntu/debian/rules (original) +++ pypy/build/ubuntu/debian/rules Fri Mar 19 21:06:07 2010 @@ -52,12 +52,11 @@ dh_install -i find debian/pypy-lib -name "*.pyc" | xargs rm -rf find debian/pypy-dev -name "*.pyc" | xargs rm -rf - rm -f debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE - rm -f debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py - rm -f debian/pypy-lib/usr/share/pypy-1.2/pypy/lib/app_test/ctypes_tests/_ctypes_test.o - rm -rf debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/c/winproj/ - chmod a-x debian/pypy-lib/usr/share/pypy-1.2/lib-python/2.5.2/idlelib/idle.bat - chmod a-x debian/pypy-dev/usr/share/pypy-1.2/pypy/translator/cli/src/pypylib.dll + rm debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE + rm debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py + rm debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/app_test/ctypes_tests/_ctypes_test.o + rm -r debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/c/winproj/ + chmod a-x debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/idlelib/idle.bat install-arch: dh_testdir From getxsick at codespeak.net Fri Mar 19 21:07:56 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 19 Mar 2010 21:07:56 +0100 (CET) Subject: [pypy-svn] r72427 - pypy/build/ubuntu/debian Message-ID: <20100319200756.AA65C282BE0@codespeak.net> Author: getxsick Date: Fri Mar 19 21:07:29 2010 New Revision: 72427 Modified: pypy/build/ubuntu/debian/changelog Log: update changelog Modified: pypy/build/ubuntu/debian/changelog ============================================================================== --- pypy/build/ubuntu/debian/changelog (original) +++ pypy/build/ubuntu/debian/changelog Fri Mar 19 21:07:29 2010 @@ -1,4 +1,4 @@ -pypy (1.2.0-1) unstable; urgency=low +pypy (1.2.0-3) jaunty; urgency=low * New upstream release. * New maintainer. @@ -6,9 +6,8 @@ * Rename pypy-translate to rpycompile. * Add pypy-dotviewer package. * Run tests (-A, lib-python, JIT) when binaries are built. - * Switch to dpkg-source 3.0 (native) format. - -- Bartosz Skowron Tue, 02 Mar 2010 18:08:37 +0100 + -- Bartosz Skowron Tue, 16 Mar 2010 19:17:36 +0100 pypy (1.0.0-svn55443-2) unstable; urgency=low From benjamin at codespeak.net Fri Mar 19 21:38:21 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 19 Mar 2010 21:38:21 +0100 (CET) Subject: [pypy-svn] r72428 - in pypy/trunk/pypy: lib/app_test/ctypes_tests module/cpyext/include rlib/rsdl/macosx-sdl-main translator/c/src translator/c/src/libffi_msvc translator/platform/test/include Message-ID: <20100319203821.7D0C3282BD4@codespeak.net> Author: benjamin Date: Fri Mar 19 21:38:17 2010 New Revision: 72428 Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/_ctypes_test.c (props changed) pypy/trunk/pypy/module/cpyext/include/floatobject.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/methodobject.h (contents, props changed) pypy/trunk/pypy/rlib/rsdl/macosx-sdl-main/SDLMain.h (props changed) pypy/trunk/pypy/translator/c/src/asm_ppc.h (props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.c (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.h (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi_common.h (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/fficonfig.h (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/ffitarget.h (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/prep_cif.c (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/pypy_ffi.c (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/types.c (contents, props changed) pypy/trunk/pypy/translator/c/src/libffi_msvc/win32.c (contents, props changed) pypy/trunk/pypy/translator/platform/test/include/test.h (props changed) Log: set svn:eol-style Modified: pypy/trunk/pypy/module/cpyext/include/floatobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/floatobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/floatobject.h Fri Mar 19 21:38:17 2010 @@ -1,16 +1,16 @@ - -/* Float object interface */ - -#ifndef Py_FLOATOBJECT_H -#define Py_FLOATOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - - -PyObject* PyFloat_FromDouble(double); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_FLOATOBJECT_H */ + +/* Float object interface */ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyObject* PyFloat_FromDouble(double); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ Modified: pypy/trunk/pypy/module/cpyext/include/methodobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/methodobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/methodobject.h Fri Mar 19 21:38:17 2010 @@ -1,36 +1,36 @@ - -/* Method object interface */ - -#ifndef Py_METHODOBJECT_H -#define Py_METHODOBJECT_H -#ifdef __cplusplus -extern "C" { -#endif - -typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); -typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, - PyObject *); -typedef PyObject *(*PyNoArgsFunction)(PyObject *); - -struct PyMethodDef { - const char *ml_name; /* The name of the built-in function/method */ - PyCFunction ml_meth; /* The C function that implements it */ - int ml_flags; /* Combination of METH_xxx flags, which mostly - describe the args expected by the C func */ - const char *ml_doc; /* The __doc__ attribute, or NULL */ -}; -typedef struct PyMethodDef PyMethodDef; - -/* Flag passed to newmethodobject */ -#define METH_OLDARGS 0x0000 -#define METH_VARARGS 0x0001 -#define METH_KEYWORDS 0x0002 -/* METH_NOARGS and METH_O must not be combined with the flags above. */ -#define METH_NOARGS 0x0004 -#define METH_O 0x0008 - - -#ifdef __cplusplus -} -#endif -#endif /* !Py_METHODOBJECT_H */ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +/* Flag passed to newmethodobject */ +#define METH_OLDARGS 0x0000 +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.c (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.c Fri Mar 19 21:38:17 2010 @@ -1,480 +1,480 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. - Copyright (c) 2002 Ranjit Mathew - Copyright (c) 2002 Bo Thorsen - Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -extern void ffi_fatalerror(char *msg); - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) - { - *(void **) argp = ecif->rvalue; - argp += sizeof(void *); - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(void *) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void *)); - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - - if (argp - stack > ecif->cif->bytes) - { - ffi_fatalerror("FFI BUG: not enough stack space for arguments"); - } - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: -#ifdef _WIN64 - case FFI_TYPE_POINTER: -#endif - cif->flags = FFI_TYPE_SINT64; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -#ifdef _WIN32 -/*@-declundef@*/ -/*@-exportheader@*/ -extern int -ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -/*@-declundef@*/ -/*@-exportheader@*/ -extern int -ffi_call_STDCALL(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ -#endif - -#ifdef _WIN64 -extern int -ffi_call_AMD64(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -#endif - -int -ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { -#if !defined(_WIN64) - case FFI_SYSV: - /*@-usedef@*/ - return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - - case FFI_STDCALL: - /*@-usedef@*/ - return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; -#else - case FFI_SYSV: - /*@-usedef@*/ - /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ - return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; -#endif - - default: - FFI_ASSERT(0); - break; - } - return -1; /* theller: Hrm. */ -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -/* This function is jumped to by the trampoline */ - -#ifdef _WIN64 -void * -#else -static void __fastcall -#endif -ffi_closure_SYSV (ffi_closure *closure, int *argp) -{ - // this is our return value storage - long double res; - - // our various things... - ffi_cif *cif; - void **arg_area; - unsigned short rtype; - void *resp = (void*)&res; - void *args = &argp[1]; - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - - /* this call will initialize ARG_AREA, such that each - * element in that array points to the corresponding - * value on the stack; and if the function returns - * a structure, it will re-set RESP to point to the - * structure return address. */ - - ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - -#if defined(_WIN32) && !defined(_WIN64) -#ifdef _MSC_VER - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - _asm mov eax, resp ; - _asm mov eax, [eax] ; - } - else if (rtype == FFI_TYPE_FLOAT) - { - _asm mov eax, resp ; - _asm fld DWORD PTR [eax] ; -// asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - _asm mov eax, resp ; - _asm fld QWORD PTR [eax] ; -// asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { -// asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - _asm mov edx, resp ; - _asm mov eax, [edx] ; - _asm mov edx, [edx + 4] ; -// asm ("movl 0(%0),%%eax;" -// "movl 4(%0),%%edx" -// : : "r"(resp) -// : "eax", "edx"); - } -#else - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax;" - "movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -#endif -#endif - -#ifdef _WIN64 - /* The result is returned in rax. This does the right thing for - result types except for floats; we have to 'mov xmm0, rax' in the - caller to correct this. - */ - return *(void **)resp; -#endif -} - -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if ( cif->rtype->type == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(char *) - 1) & (size_t) argp) { - argp = (char *) ALIGN(argp, sizeof(char*)); - } - - z = (*p_arg)->size; - - /* because we're little endian, this is what it turns into. */ - - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } - - return; -} - -/* the cif must already be prep'ed */ -extern void ffi_closure_OUTER(); - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - short bytes; - char *tramp; -#ifdef _WIN64 - int mask; -#endif - FFI_ASSERT (cif->abi == FFI_SYSV); - - if (cif->abi == FFI_SYSV) - bytes = 0; -#if !defined(_WIN64) - else if (cif->abi == FFI_STDCALL) - bytes = cif->bytes; -#endif - else - return FFI_BAD_ABI; - - tramp = &closure->tramp[0]; - -#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1 -#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*) -#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short) -#define INT(x) *(int*)tramp = x, tramp += sizeof(int) - -#ifdef _WIN64 - if (cif->nargs >= 1 && - (cif->arg_types[0]->type == FFI_TYPE_FLOAT - || cif->arg_types[0]->type == FFI_TYPE_DOUBLE)) - mask |= 1; - if (cif->nargs >= 2 && - (cif->arg_types[1]->type == FFI_TYPE_FLOAT - || cif->arg_types[1]->type == FFI_TYPE_DOUBLE)) - mask |= 2; - if (cif->nargs >= 3 && - (cif->arg_types[2]->type == FFI_TYPE_FLOAT - || cif->arg_types[2]->type == FFI_TYPE_DOUBLE)) - mask |= 4; - if (cif->nargs >= 4 && - (cif->arg_types[3]->type == FFI_TYPE_FLOAT - || cif->arg_types[3]->type == FFI_TYPE_DOUBLE)) - mask |= 8; - - /* 41 BB ---- mov r11d,mask */ - BYTES("\x41\xBB"); INT(mask); - - /* 48 B8 -------- mov rax, closure */ - BYTES("\x48\xB8"); POINTER(closure); - - /* 49 BA -------- mov r10, ffi_closure_OUTER */ - BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER); - - /* 41 FF E2 jmp r10 */ - BYTES("\x41\xFF\xE2"); - -#else - - /* mov ecx, closure */ - BYTES("\xb9"); POINTER(closure); - - /* mov edx, esp */ - BYTES("\x8b\xd4"); - - /* call ffi_closure_SYSV */ - BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4)); - - /* ret bytes */ - BYTES("\xc2"); - SHORT(bytes); - -#endif - - if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE) - ffi_fatalerror("FFI_TRAMPOLINE_SIZE too small in " __FILE__); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. + Copyright (c) 2002 Ranjit Mathew + Copyright (c) 2002 Bo Thorsen + Copyright (c) 2002 Roger Sayle + + x86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include + +#include + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ + +extern void ffi_fatalerror(char *msg); + +/*@-exportheader@*/ +void ffi_prep_args(char *stack, extended_cif *ecif) +/*@=exportheader@*/ +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += sizeof(void *); + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(void *) - 1) & (size_t) argp) + argp = (char *) ALIGN(argp, sizeof(void *)); + + z = (*p_arg)->size; + if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_SINT32: + *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); + break; + + case FFI_TYPE_UINT32: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + break; + + default: + FFI_ASSERT(0); + } + } + else + { + memcpy(argp, *p_argv, z); + } + p_argv++; + argp += z; + } + + if (argp - stack > ecif->cif->bytes) + { + ffi_fatalerror("FFI BUG: not enough stack space for arguments"); + } + return; +} + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + case FFI_TYPE_STRUCT: + case FFI_TYPE_SINT64: + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + case FFI_TYPE_LONGDOUBLE: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_UINT64: +#ifdef _WIN64 + case FFI_TYPE_POINTER: +#endif + cif->flags = FFI_TYPE_SINT64; + break; + + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +#ifdef _WIN32 +/*@-declundef@*/ +/*@-exportheader@*/ +extern int +ffi_call_SYSV(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +/*@=declundef@*/ +/*@=exportheader@*/ + +/*@-declundef@*/ +/*@-exportheader@*/ +extern int +ffi_call_STDCALL(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +/*@=declundef@*/ +/*@=exportheader@*/ +#endif + +#ifdef _WIN64 +extern int +ffi_call_AMD64(void (*)(char *, extended_cif *), + /*@out@*/ extended_cif *, + unsigned, unsigned, + /*@out@*/ unsigned *, + void (*fn)()); +#endif + +int +ffi_call(/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return */ + /* value address then we need to make one */ + + if ((rvalue == NULL) && + (cif->rtype->type == FFI_TYPE_STRUCT)) + { + /*@-sysunrecog@*/ + ecif.rvalue = alloca(cif->rtype->size); + /*@=sysunrecog@*/ + } + else + ecif.rvalue = rvalue; + + + switch (cif->abi) + { +#if !defined(_WIN64) + case FFI_SYSV: + /*@-usedef@*/ + return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + /*@=usedef@*/ + break; + + case FFI_STDCALL: + /*@-usedef@*/ + return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + /*@=usedef@*/ + break; +#else + case FFI_SYSV: + /*@-usedef@*/ + /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ + return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40, + cif->flags, ecif.rvalue, fn); + /*@=usedef@*/ + break; +#endif + + default: + FFI_ASSERT(0); + break; + } + return -1; /* theller: Hrm. */ +} + + +/** private members **/ + +static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, + void** args, ffi_cif* cif); +/* This function is jumped to by the trampoline */ + +#ifdef _WIN64 +void * +#else +static void __fastcall +#endif +ffi_closure_SYSV (ffi_closure *closure, int *argp) +{ + // this is our return value storage + long double res; + + // our various things... + ffi_cif *cif; + void **arg_area; + unsigned short rtype; + void *resp = (void*)&res; + void *args = &argp[1]; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void*)); + + /* this call will initialize ARG_AREA, such that each + * element in that array points to the corresponding + * value on the stack; and if the function returns + * a structure, it will re-set RESP to point to the + * structure return address. */ + + ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + rtype = cif->flags; + +#if defined(_WIN32) && !defined(_WIN64) +#ifdef _MSC_VER + /* now, do a generic return based on the value of rtype */ + if (rtype == FFI_TYPE_INT) + { + _asm mov eax, resp ; + _asm mov eax, [eax] ; + } + else if (rtype == FFI_TYPE_FLOAT) + { + _asm mov eax, resp ; + _asm fld DWORD PTR [eax] ; +// asm ("flds (%0)" : : "r" (resp) : "st" ); + } + else if (rtype == FFI_TYPE_DOUBLE) + { + _asm mov eax, resp ; + _asm fld QWORD PTR [eax] ; +// asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_LONGDOUBLE) + { +// asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_SINT64) + { + _asm mov edx, resp ; + _asm mov eax, [edx] ; + _asm mov edx, [edx + 4] ; +// asm ("movl 0(%0),%%eax;" +// "movl 4(%0),%%edx" +// : : "r"(resp) +// : "eax", "edx"); + } +#else + /* now, do a generic return based on the value of rtype */ + if (rtype == FFI_TYPE_INT) + { + asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); + } + else if (rtype == FFI_TYPE_FLOAT) + { + asm ("flds (%0)" : : "r" (resp) : "st" ); + } + else if (rtype == FFI_TYPE_DOUBLE) + { + asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_LONGDOUBLE) + { + asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); + } + else if (rtype == FFI_TYPE_SINT64) + { + asm ("movl 0(%0),%%eax;" + "movl 4(%0),%%edx" + : : "r"(resp) + : "eax", "edx"); + } +#endif +#endif + +#ifdef _WIN64 + /* The result is returned in rax. This does the right thing for + result types except for floats; we have to 'mov xmm0, rax' in the + caller to correct this. + */ + return *(void **)resp; +#endif +} + +/*@-exportheader@*/ +static void +ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, + void **avalue, ffi_cif *cif) +/*@=exportheader@*/ +{ + register unsigned int i; + register void **p_argv; + register char *argp; + register ffi_type **p_arg; + + argp = stack; + + if ( cif->rtype->type == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) argp; + argp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + + /* Align if necessary */ + if ((sizeof(char *) - 1) & (size_t) argp) { + argp = (char *) ALIGN(argp, sizeof(char*)); + } + + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + + p_argv++; + argp += z; + } + + return; +} + +/* the cif must already be prep'ed */ +extern void ffi_closure_OUTER(); + +ffi_status +ffi_prep_closure (ffi_closure* closure, + ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data) +{ + short bytes; + char *tramp; +#ifdef _WIN64 + int mask; +#endif + FFI_ASSERT (cif->abi == FFI_SYSV); + + if (cif->abi == FFI_SYSV) + bytes = 0; +#if !defined(_WIN64) + else if (cif->abi == FFI_STDCALL) + bytes = cif->bytes; +#endif + else + return FFI_BAD_ABI; + + tramp = &closure->tramp[0]; + +#define BYTES(text) memcpy(tramp, text, sizeof(text)), tramp += sizeof(text)-1 +#define POINTER(x) *(void**)tramp = (void*)(x), tramp += sizeof(void*) +#define SHORT(x) *(short*)tramp = x, tramp += sizeof(short) +#define INT(x) *(int*)tramp = x, tramp += sizeof(int) + +#ifdef _WIN64 + if (cif->nargs >= 1 && + (cif->arg_types[0]->type == FFI_TYPE_FLOAT + || cif->arg_types[0]->type == FFI_TYPE_DOUBLE)) + mask |= 1; + if (cif->nargs >= 2 && + (cif->arg_types[1]->type == FFI_TYPE_FLOAT + || cif->arg_types[1]->type == FFI_TYPE_DOUBLE)) + mask |= 2; + if (cif->nargs >= 3 && + (cif->arg_types[2]->type == FFI_TYPE_FLOAT + || cif->arg_types[2]->type == FFI_TYPE_DOUBLE)) + mask |= 4; + if (cif->nargs >= 4 && + (cif->arg_types[3]->type == FFI_TYPE_FLOAT + || cif->arg_types[3]->type == FFI_TYPE_DOUBLE)) + mask |= 8; + + /* 41 BB ---- mov r11d,mask */ + BYTES("\x41\xBB"); INT(mask); + + /* 48 B8 -------- mov rax, closure */ + BYTES("\x48\xB8"); POINTER(closure); + + /* 49 BA -------- mov r10, ffi_closure_OUTER */ + BYTES("\x49\xBA"); POINTER(ffi_closure_OUTER); + + /* 41 FF E2 jmp r10 */ + BYTES("\x41\xFF\xE2"); + +#else + + /* mov ecx, closure */ + BYTES("\xb9"); POINTER(closure); + + /* mov edx, esp */ + BYTES("\x8b\xd4"); + + /* call ffi_closure_SYSV */ + BYTES("\xe8"); POINTER((char*)&ffi_closure_SYSV - (tramp + 4)); + + /* ret bytes */ + BYTES("\xc2"); + SHORT(bytes); + +#endif + + if (tramp - &closure->tramp[0] > FFI_TRAMPOLINE_SIZE) + ffi_fatalerror("FFI_TRAMPOLINE_SIZE too small in " __FILE__); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.h (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi.h Fri Mar 19 21:38:17 2010 @@ -1,315 +1,315 @@ -/* -----------------------------------------------------------------*-C-*- - libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------- - The basic API is described in the README file. - - The raw API is designed to bypass some of the argument packing - and unpacking on architectures for which it can be avoided. - - The closure API allows interpreted functions to be packaged up - inside a C function pointer, so that they can be called as C functions, - with no understanding on the client side that they are interpreted. - It can also be used in other cases in which it is necessary to package - up a user specified parameter and a function pointer as a single - function pointer. - - The closure API must be implemented in order to get its functionality, - e.g. for use by gij. Routines are provided to emulate the raw API - if the underlying platform doesn't allow faster implementation. - - More details on the raw and cloure API can be found in: - - http://gcc.gnu.org/ml/java/1999-q3/msg00138.html - - and - - http://gcc.gnu.org/ml/java/1999-q3/msg00174.html - -------------------------------------------------------------------- */ - -#ifndef LIBFFI_H -#define LIBFFI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Specify which architecture libffi is configured for. */ -//XXX #define X86 - -/* ---- System configuration information --------------------------------- */ - -#include - -#ifndef LIBFFI_ASM - -#include -#include - -/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). - But we can find it either under the correct ANSI name, or under GNU - C's internal name. */ -#ifdef LONG_LONG_MAX -# define FFI_LONG_LONG_MAX LONG_LONG_MAX -#else -# ifdef LLONG_MAX -# define FFI_LONG_LONG_MAX LLONG_MAX -# else -# ifdef __GNUC__ -# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ -# endif -# ifdef _MSC_VER -# define FFI_LONG_LONG_MAX _I64_MAX -# endif -# endif -#endif - -#if SCHAR_MAX == 127 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else - #error "char size not supported" -#endif - -#if SHRT_MAX == 32767 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SHRT_MAX == 2147483647 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else - #error "short size not supported" -#endif - -#if INT_MAX == 32767 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif INT_MAX == 2147483647 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif INT_MAX == 9223372036854775807 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else - #error "int size not supported" -#endif - -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 -#if LONG_MAX == 2147483647 -# if FFI_LONG_LONG_MAX != 9223372036854775807 - #error "no 64-bit data type supported" -# endif -#elif LONG_MAX != 9223372036854775807 - #error "long size not supported" -#endif - -/* The closure code assumes that this works on pointers, i.e. a size_t */ -/* can hold a pointer. */ - -typedef struct _ffi_type -{ - size_t size; - unsigned short alignment; - unsigned short type; - /*@null@*/ struct _ffi_type **elements; -} ffi_type; - -/* These are defined in types.c */ -extern ffi_type ffi_type_void; -extern ffi_type ffi_type_uint8; -extern ffi_type ffi_type_sint8; -extern ffi_type ffi_type_uint16; -extern ffi_type ffi_type_sint16; -extern ffi_type ffi_type_uint32; -extern ffi_type ffi_type_sint32; -extern ffi_type ffi_type_uint64; -extern ffi_type ffi_type_sint64; -extern ffi_type ffi_type_float; -extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; -extern ffi_type ffi_type_pointer; - - -typedef enum { - FFI_OK = 0, - FFI_BAD_TYPEDEF, - FFI_BAD_ABI -} ffi_status; - -typedef unsigned FFI_TYPE; - -typedef struct { - ffi_abi abi; - unsigned nargs; - /*@dependent@*/ ffi_type **arg_types; - /*@dependent@*/ ffi_type *rtype; - unsigned bytes; - unsigned flags; -#ifdef FFI_EXTRA_CIF_FIELDS - FFI_EXTRA_CIF_FIELDS; -#endif -} ffi_cif; - -/* ---- Definitions for the raw API -------------------------------------- */ - -#ifdef _WIN64 -#define FFI_SIZEOF_ARG 8 -#else -#define FFI_SIZEOF_ARG 4 -#endif - -typedef union { - ffi_sarg sint; - ffi_arg uint; - float flt; - char data[FFI_SIZEOF_ARG]; - void* ptr; -} ffi_raw; - -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_raw_size (ffi_cif *cif); - -/* This is analogous to the raw API, except it uses Java parameter */ -/* packing, even on 64-bit machines. I.e. on 64-bit machines */ -/* longs and doubles are followed by an empty 64-bit word. */ - -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *avalue); - -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); -size_t ffi_java_raw_size (ffi_cif *cif); - -/* ---- Definitions for closures ----------------------------------------- */ - -#if FFI_CLOSURES - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif *cif; - void (*fun)(ffi_cif*,void*,void**,void*); - void *user_data; -} ffi_closure; - -ffi_status -ffi_prep_closure (ffi_closure*, - ffi_cif *, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data); - -typedef struct { - char tramp[FFI_TRAMPOLINE_SIZE]; - - ffi_cif *cif; - -#if !FFI_NATIVE_RAW_API - - /* if this is enabled, then a raw closure has the same layout - as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ - - void (*translate_args)(ffi_cif*,void*,void**,void*); - void *this_closure; - -#endif - - void (*fun)(ffi_cif*,void*,ffi_raw*,void*); - void *user_data; - -} ffi_raw_closure; - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data); - -#endif /* FFI_CLOSURES */ - -/* ---- Public interface definition -------------------------------------- */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, - unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes); - -int -ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue); - -/* Useful for eliminating compiler warnings */ -#define FFI_FN(f) ((void (*)())f) - -/* ---- Definitions shared with assembly code ---------------------------- */ - -#endif - -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 -#if 1 -#define FFI_TYPE_LONGDOUBLE 4 -#else -#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 - -/* This should always refer to the last type code (for sanity checks) */ -#define FFI_TYPE_LAST FFI_TYPE_POINTER - -#ifdef __cplusplus -} -#endif - -#endif - +/* -----------------------------------------------------------------*-C-*- + libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +/* ------------------------------------------------------------------- + The basic API is described in the README file. + + The raw API is designed to bypass some of the argument packing + and unpacking on architectures for which it can be avoided. + + The closure API allows interpreted functions to be packaged up + inside a C function pointer, so that they can be called as C functions, + with no understanding on the client side that they are interpreted. + It can also be used in other cases in which it is necessary to package + up a user specified parameter and a function pointer as a single + function pointer. + + The closure API must be implemented in order to get its functionality, + e.g. for use by gij. Routines are provided to emulate the raw API + if the underlying platform doesn't allow faster implementation. + + More details on the raw and cloure API can be found in: + + http://gcc.gnu.org/ml/java/1999-q3/msg00138.html + + and + + http://gcc.gnu.org/ml/java/1999-q3/msg00174.html + -------------------------------------------------------------------- */ + +#ifndef LIBFFI_H +#define LIBFFI_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Specify which architecture libffi is configured for. */ +//XXX #define X86 + +/* ---- System configuration information --------------------------------- */ + +#include + +#ifndef LIBFFI_ASM + +#include +#include + +/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). + But we can find it either under the correct ANSI name, or under GNU + C's internal name. */ +#ifdef LONG_LONG_MAX +# define FFI_LONG_LONG_MAX LONG_LONG_MAX +#else +# ifdef LLONG_MAX +# define FFI_LONG_LONG_MAX LLONG_MAX +# else +# ifdef __GNUC__ +# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ +# endif +# ifdef _MSC_VER +# define FFI_LONG_LONG_MAX _I64_MAX +# endif +# endif +#endif + +#if SCHAR_MAX == 127 +# define ffi_type_uchar ffi_type_uint8 +# define ffi_type_schar ffi_type_sint8 +#else + #error "char size not supported" +#endif + +#if SHRT_MAX == 32767 +# define ffi_type_ushort ffi_type_uint16 +# define ffi_type_sshort ffi_type_sint16 +#elif SHRT_MAX == 2147483647 +# define ffi_type_ushort ffi_type_uint32 +# define ffi_type_sshort ffi_type_sint32 +#else + #error "short size not supported" +#endif + +#if INT_MAX == 32767 +# define ffi_type_uint ffi_type_uint16 +# define ffi_type_sint ffi_type_sint16 +#elif INT_MAX == 2147483647 +# define ffi_type_uint ffi_type_uint32 +# define ffi_type_sint ffi_type_sint32 +#elif INT_MAX == 9223372036854775807 +# define ffi_type_uint ffi_type_uint64 +# define ffi_type_sint ffi_type_sint64 +#else + #error "int size not supported" +#endif + +#define ffi_type_ulong ffi_type_uint64 +#define ffi_type_slong ffi_type_sint64 +#if LONG_MAX == 2147483647 +# if FFI_LONG_LONG_MAX != 9223372036854775807 + #error "no 64-bit data type supported" +# endif +#elif LONG_MAX != 9223372036854775807 + #error "long size not supported" +#endif + +/* The closure code assumes that this works on pointers, i.e. a size_t */ +/* can hold a pointer. */ + +typedef struct _ffi_type +{ + size_t size; + unsigned short alignment; + unsigned short type; + /*@null@*/ struct _ffi_type **elements; +} ffi_type; + +/* These are defined in types.c */ +extern ffi_type ffi_type_void; +extern ffi_type ffi_type_uint8; +extern ffi_type ffi_type_sint8; +extern ffi_type ffi_type_uint16; +extern ffi_type ffi_type_sint16; +extern ffi_type ffi_type_uint32; +extern ffi_type ffi_type_sint32; +extern ffi_type ffi_type_uint64; +extern ffi_type ffi_type_sint64; +extern ffi_type ffi_type_float; +extern ffi_type ffi_type_double; +extern ffi_type ffi_type_longdouble; +extern ffi_type ffi_type_pointer; + + +typedef enum { + FFI_OK = 0, + FFI_BAD_TYPEDEF, + FFI_BAD_ABI +} ffi_status; + +typedef unsigned FFI_TYPE; + +typedef struct { + ffi_abi abi; + unsigned nargs; + /*@dependent@*/ ffi_type **arg_types; + /*@dependent@*/ ffi_type *rtype; + unsigned bytes; + unsigned flags; +#ifdef FFI_EXTRA_CIF_FIELDS + FFI_EXTRA_CIF_FIELDS; +#endif +} ffi_cif; + +/* ---- Definitions for the raw API -------------------------------------- */ + +#ifdef _WIN64 +#define FFI_SIZEOF_ARG 8 +#else +#define FFI_SIZEOF_ARG 4 +#endif + +typedef union { + ffi_sarg sint; + ffi_arg uint; + float flt; + char data[FFI_SIZEOF_ARG]; + void* ptr; +} ffi_raw; + +void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ ffi_raw *avalue); + +void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); +void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +size_t ffi_raw_size (ffi_cif *cif); + +/* This is analogous to the raw API, except it uses Java parameter */ +/* packing, even on 64-bit machines. I.e. on 64-bit machines */ +/* longs and doubles are followed by an empty 64-bit word. */ + +void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ ffi_raw *avalue); + +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +size_t ffi_java_raw_size (ffi_cif *cif); + +/* ---- Definitions for closures ----------------------------------------- */ + +#if FFI_CLOSURES + +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + ffi_cif *cif; + void (*fun)(ffi_cif*,void*,void**,void*); + void *user_data; +} ffi_closure; + +ffi_status +ffi_prep_closure (ffi_closure*, + ffi_cif *, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data); + +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_raw*,void*); + void *user_data; + +} ffi_raw_closure; + +ffi_status +ffi_prep_raw_closure (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data); + +ffi_status +ffi_prep_java_raw_closure (ffi_raw_closure*, + ffi_cif *cif, + void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void *user_data); + +#endif /* FFI_CLOSURES */ + +/* ---- Public interface definition -------------------------------------- */ + +ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, + ffi_abi abi, + unsigned int nargs, + /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, + /*@dependent@*/ ffi_type **atypes); + +int +ffi_call(/*@dependent@*/ ffi_cif *cif, + void (*fn)(), + /*@out@*/ void *rvalue, + /*@dependent@*/ void **avalue); + +/* Useful for eliminating compiler warnings */ +#define FFI_FN(f) ((void (*)())f) + +/* ---- Definitions shared with assembly code ---------------------------- */ + +#endif + +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 +#if 1 +#define FFI_TYPE_LONGDOUBLE 4 +#else +#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 + +/* This should always refer to the last type code (for sanity checks) */ +#define FFI_TYPE_LAST FFI_TYPE_POINTER + +#ifdef __cplusplus +} +#endif + +#endif + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi_common.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi_common.h (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/ffi_common.h Fri Mar 19 21:38:17 2010 @@ -1,77 +1,77 @@ -/* ----------------------------------------------------------------------- - ffi_common.h - Copyright (c) 1996 Red Hat, Inc. - - Common internal definitions and macros. Only necessary for building - libffi. - ----------------------------------------------------------------------- */ - -#ifndef FFI_COMMON_H -#define FFI_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* Check for the existence of memcpy. */ -#if STDC_HEADERS -# include -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# endif -#endif - -#if defined(FFI_DEBUG) -#include -#endif - -#ifdef FFI_DEBUG -/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); -void ffi_stop_here(void); -void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); - -#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) -#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) -#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) -#else -#define FFI_ASSERT(x) -#define FFI_ASSERT_AT(x, f, l) -#define FFI_ASSERT_VALID_TYPE(x) -#endif - -#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif); - -/* Extended cif, used in callback from assembly routine */ -typedef struct -{ - /*@dependent@*/ ffi_cif *cif; - /*@dependent@*/ void *rvalue; - /*@dependent@*/ void **avalue; -} extended_cif; - -/* Terse sized type definitions. */ -typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); -typedef signed int SINT8 __attribute__((__mode__(__QI__))); -typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); -typedef signed int SINT16 __attribute__((__mode__(__HI__))); -typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); -typedef signed int SINT32 __attribute__((__mode__(__SI__))); -typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); -typedef signed int SINT64 __attribute__((__mode__(__DI__))); - -typedef float FLOAT32; - - -#ifdef __cplusplus -} -#endif - -#endif - - +/* ----------------------------------------------------------------------- + ffi_common.h - Copyright (c) 1996 Red Hat, Inc. + + Common internal definitions and macros. Only necessary for building + libffi. + ----------------------------------------------------------------------- */ + +#ifndef FFI_COMMON_H +#define FFI_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* Check for the existence of memcpy. */ +#if STDC_HEADERS +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#if defined(FFI_DEBUG) +#include +#endif + +#ifdef FFI_DEBUG +/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); +void ffi_stop_here(void); +void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); + +#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) +#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) +#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) +#else +#define FFI_ASSERT(x) +#define FFI_ASSERT_AT(x, f, l) +#define FFI_ASSERT_VALID_TYPE(x) +#endif + +#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) + +/* Perform machine dependent cif processing */ +ffi_status ffi_prep_cif_machdep(ffi_cif *cif); + +/* Extended cif, used in callback from assembly routine */ +typedef struct +{ + /*@dependent@*/ ffi_cif *cif; + /*@dependent@*/ void *rvalue; + /*@dependent@*/ void **avalue; +} extended_cif; + +/* Terse sized type definitions. */ +typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); +typedef signed int SINT8 __attribute__((__mode__(__QI__))); +typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); +typedef signed int SINT16 __attribute__((__mode__(__HI__))); +typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); +typedef signed int SINT32 __attribute__((__mode__(__SI__))); +typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); +typedef signed int SINT64 __attribute__((__mode__(__DI__))); + +typedef float FLOAT32; + + +#ifdef __cplusplus +} +#endif + +#endif + + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/fficonfig.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/fficonfig.h (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/fficonfig.h Fri Mar 19 21:38:17 2010 @@ -1,96 +1,96 @@ -/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ - -/* fficonfig.h. Generated automatically by configure. */ -/* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define this for MSVC, but not for mingw32! */ -#ifdef _MSC_VER -#define __attribute__(x) /* */ -#endif -#define alloca _alloca - -/*----------------------------------------------------------------*/ - -/* Define if using alloca.c. */ -/* #undef C_ALLOCA */ - -/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. - This function is required for alloca.c support on those systems. */ -/* #undef CRAY_STACKSEG_END */ - -/* Define if you have alloca, as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define if you have and it should be used (not on Ultrix). */ -/* #define HAVE_ALLOCA_H 1 */ - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown - */ -/* #undef STACK_DIRECTION */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you have the memcpy function. */ -#define HAVE_MEMCPY 1 - -/* Define if read-only mmap of a plain file works. */ -//#define HAVE_MMAP_FILE 1 - -/* Define if mmap of /dev/zero works. */ -//#define HAVE_MMAP_DEV_ZERO 1 - -/* Define if mmap with MAP_ANON(YMOUS) works. */ -//#define HAVE_MMAP_ANON 1 - -/* The number of bytes in type double */ -#define SIZEOF_DOUBLE 8 - -/* The number of bytes in type long double */ -#define SIZEOF_LONG_DOUBLE 12 - -/* Define if you have the long double type and it is bigger than a double */ -#define HAVE_LONG_DOUBLE 1 - -/* whether byteorder is bigendian */ -/* #undef WORDS_BIGENDIAN */ - -/* Define if the host machine stores words of multi-word integers in - big-endian order. */ -/* #undef HOST_WORDS_BIG_ENDIAN */ - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 1234 - -/* Define if your assembler and linker support unaligned PC relative relocs. */ -/* #undef HAVE_AS_SPARC_UA_PCREL */ - -/* Define if your assembler supports .register. */ -/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ - -/* Define if .eh_frame sections should be read-only. */ -/* #undef HAVE_RO_EH_FRAME */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -/* #define EH_FRAME_FLAGS "aw" */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -/* #define EH_FRAME_FLAGS "aw" */ - -/* Define this if you want extra debugging. */ -/* #undef FFI_DEBUG */ - -/* Define this is you do not want support for aggregate types. */ -/* #undef FFI_NO_STRUCTS */ - -/* Define this is you do not want support for the raw API. */ -/* #undef FFI_NO_RAW_API */ - -/* Define this if you are using Purify and want to suppress spurious messages. */ -/* #undef USING_PURIFY */ - +/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ + +/* fficonfig.h. Generated automatically by configure. */ +/* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define this for MSVC, but not for mingw32! */ +#ifdef _MSC_VER +#define __attribute__(x) /* */ +#endif +#define alloca _alloca + +/*----------------------------------------------------------------*/ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +/* #define HAVE_ALLOCA_H 1 */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you have the memcpy function. */ +#define HAVE_MEMCPY 1 + +/* Define if read-only mmap of a plain file works. */ +//#define HAVE_MMAP_FILE 1 + +/* Define if mmap of /dev/zero works. */ +//#define HAVE_MMAP_DEV_ZERO 1 + +/* Define if mmap with MAP_ANON(YMOUS) works. */ +//#define HAVE_MMAP_ANON 1 + +/* The number of bytes in type double */ +#define SIZEOF_DOUBLE 8 + +/* The number of bytes in type long double */ +#define SIZEOF_LONG_DOUBLE 12 + +/* Define if you have the long double type and it is bigger than a double */ +#define HAVE_LONG_DOUBLE 1 + +/* whether byteorder is bigendian */ +/* #undef WORDS_BIGENDIAN */ + +/* Define if the host machine stores words of multi-word integers in + big-endian order. */ +/* #undef HOST_WORDS_BIG_ENDIAN */ + +/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ +#define BYTEORDER 1234 + +/* Define if your assembler and linker support unaligned PC relative relocs. */ +/* #undef HAVE_AS_SPARC_UA_PCREL */ + +/* Define if your assembler supports .register. */ +/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ + +/* Define if .eh_frame sections should be read-only. */ +/* #undef HAVE_RO_EH_FRAME */ + +/* Define to the flags needed for the .section .eh_frame directive. */ +/* #define EH_FRAME_FLAGS "aw" */ + +/* Define to the flags needed for the .section .eh_frame directive. */ +/* #define EH_FRAME_FLAGS "aw" */ + +/* Define this if you want extra debugging. */ +/* #undef FFI_DEBUG */ + +/* Define this is you do not want support for aggregate types. */ +/* #undef FFI_NO_STRUCTS */ + +/* Define this is you do not want support for the raw API. */ +/* #undef FFI_NO_RAW_API */ + +/* Define this if you are using Purify and want to suppress spurious messages. */ +/* #undef USING_PURIFY */ + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/ffitarget.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/ffitarget.h (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/ffitarget.h Fri Mar 19 21:38:17 2010 @@ -1,85 +1,85 @@ -/* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for x86 and x86-64. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if defined (X86_64) && defined (__i386__) -#undef X86_64 -#define X86 -#endif - -/* ---- Generic type definitions ----------------------------------------- */ - -#ifndef LIBFFI_ASM -#ifndef _WIN64 -typedef unsigned long ffi_arg; -#else -typedef unsigned __int64 ffi_arg; -#endif -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - - /* ---- Intel x86 Win32 ---------- */ - FFI_SYSV, -#ifndef _WIN64 - FFI_STDCALL, -#endif - /* TODO: Add fastcall support for the sake of completeness */ - FFI_DEFAULT_ABI = FFI_SYSV, - - /* ---- Intel x86 and AMD x86-64 - */ -/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */ -/* FFI_SYSV, */ -/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */ -/* #ifdef __i386__ */ -/* FFI_DEFAULT_ABI = FFI_SYSV, */ -/* #else */ -/* FFI_DEFAULT_ABI = FFI_UNIX64, */ -/* #endif */ -/* #endif */ - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; -#endif - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 - -#ifdef _WIN64 -#define FFI_TRAMPOLINE_SIZE 29 -#define FFI_NATIVE_RAW_API 0 -#else -#define FFI_TRAMPOLINE_SIZE 15 -#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ -#endif - -#endif - +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + Target configuration macros for x86 and x86-64. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#if defined (X86_64) && defined (__i386__) +#undef X86_64 +#define X86 +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +#ifndef _WIN64 +typedef unsigned long ffi_arg; +#else +typedef unsigned __int64 ffi_arg; +#endif +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + + /* ---- Intel x86 Win32 ---------- */ + FFI_SYSV, +#ifndef _WIN64 + FFI_STDCALL, +#endif + /* TODO: Add fastcall support for the sake of completeness */ + FFI_DEFAULT_ABI = FFI_SYSV, + + /* ---- Intel x86 and AMD x86-64 - */ +/* #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) */ +/* FFI_SYSV, */ +/* FFI_UNIX64,*/ /* Unix variants all use the same ABI for x86-64 */ +/* #ifdef __i386__ */ +/* FFI_DEFAULT_ABI = FFI_SYSV, */ +/* #else */ +/* FFI_DEFAULT_ABI = FFI_UNIX64, */ +/* #endif */ +/* #endif */ + + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 + +#ifdef _WIN64 +#define FFI_TRAMPOLINE_SIZE 29 +#define FFI_NATIVE_RAW_API 0 +#else +#define FFI_TRAMPOLINE_SIZE 15 +#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ +#endif + +#endif + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/prep_cif.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/prep_cif.c (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/prep_cif.c Fri Mar 19 21:38:17 2010 @@ -1,175 +1,175 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include -#include - - -/* Round up to FFI_SIZEOF_ARG. */ - -#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) -{ - ffi_type **ptr; - - FFI_ASSERT(arg != NULL); - - /*@-usedef@*/ - - FFI_ASSERT(arg->elements != NULL); - FFI_ASSERT(arg->size == 0); - FFI_ASSERT(arg->alignment == 0); - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT_VALID_TYPE(*ptr); - - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; - - ptr++; - } - - /* Structure size includes tail padding. This is important for - structures that fit in one register on ABIs like the PowerPC64 - Linux ABI that right justify small structs in a register. - It's also needed for nested structure layout, for example - struct A { long a; char b; }; struct B { struct A x; char y; }; - should find y at an offset of 2*sizeof(long) and result in a - total size of 3*sizeof(long). */ - arg->size = ALIGN (arg->size, arg->alignment); - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - else - return FFI_OK; - - /*@=usedef@*/ -} - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) -{ - unsigned bytes = 0; - unsigned int i; - ffi_type **ptr; - - FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT_VALID_TYPE(cif->rtype); - - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT - /* MSVC returns small structures in registers. But we have a different - workaround: pretend int32 or int64 return type, and converting to - structure afterwards. */ -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type, do this - check after the initialization. */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#if !defined __x86_64__ && !defined S390 -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif - { -#if !defined(_MSC_VER) && !defined(__MINGW32__) - /* Don't know if this is a libffi bug or not. At least on - Windows with MSVC, function call parameters are *not* - aligned in the same way as structure fields are, they are - only aligned in integer boundaries. - - This doesn't do any harm for cdecl functions and closures, - since the caller cleans up the stack, but it is wrong for - stdcall functions where the callee cleans. - */ - - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - -#endif - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#endif - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} +/* ----------------------------------------------------------------------- + prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include +#include + + +/* Round up to FFI_SIZEOF_ARG. */ + +#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) + +/* Perform machine independent initialization of aggregate type + specifications. */ + +static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) +{ + ffi_type **ptr; + + FFI_ASSERT(arg != NULL); + + /*@-usedef@*/ + + FFI_ASSERT(arg->elements != NULL); + FFI_ASSERT(arg->size == 0); + FFI_ASSERT(arg->alignment == 0); + + ptr = &(arg->elements[0]); + + while ((*ptr) != NULL) + { + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type */ + FFI_ASSERT_VALID_TYPE(*ptr); + + arg->size = ALIGN(arg->size, (*ptr)->alignment); + arg->size += (*ptr)->size; + + arg->alignment = (arg->alignment > (*ptr)->alignment) ? + arg->alignment : (*ptr)->alignment; + + ptr++; + } + + /* Structure size includes tail padding. This is important for + structures that fit in one register on ABIs like the PowerPC64 + Linux ABI that right justify small structs in a register. + It's also needed for nested structure layout, for example + struct A { long a; char b; }; struct B { struct A x; char y; }; + should find y at an offset of 2*sizeof(long) and result in a + total size of 3*sizeof(long). */ + arg->size = ALIGN (arg->size, arg->alignment); + + if (arg->size == 0) + return FFI_BAD_TYPEDEF; + else + return FFI_OK; + + /*@=usedef@*/ +} + +/* Perform machine independent ffi_cif preparation, then call + machine dependent routine. */ + +ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, + ffi_abi abi, unsigned int nargs, + /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, + /*@dependent@*/ ffi_type **atypes) +{ + unsigned bytes = 0; + unsigned int i; + ffi_type **ptr; + + FFI_ASSERT(cif != NULL); + FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); + + cif->abi = abi; + cif->arg_types = atypes; + cif->nargs = nargs; + cif->rtype = rtype; + + cif->flags = 0; + + /* Initialize the return type if necessary */ + /*@-usedef@*/ + if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) + return FFI_BAD_TYPEDEF; + /*@=usedef@*/ + + /* Perform a sanity check on the return type */ + FFI_ASSERT_VALID_TYPE(cif->rtype); + + /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ +#if !defined M68K && !defined __x86_64__ && !defined S390 + /* Make space for the return structure pointer */ + if (cif->rtype->type == FFI_TYPE_STRUCT + /* MSVC returns small structures in registers. But we have a different + workaround: pretend int32 or int64 return type, and converting to + structure afterwards. */ +#ifdef SPARC + && (cif->abi != FFI_V9 || cif->rtype->size > 32) +#endif + ) + bytes = STACK_ARG_SIZE(sizeof(void*)); +#endif + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + + /* Initialize any uninitialized aggregate type definitions */ + if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) + return FFI_BAD_TYPEDEF; + + /* Perform a sanity check on the argument type, do this + check after the initialization. */ + FFI_ASSERT_VALID_TYPE(*ptr); + +#if !defined __x86_64__ && !defined S390 +#ifdef SPARC + if (((*ptr)->type == FFI_TYPE_STRUCT + && ((*ptr)->size > 16 || cif->abi != FFI_V9)) + || ((*ptr)->type == FFI_TYPE_LONGDOUBLE + && cif->abi != FFI_V9)) + bytes += sizeof(void*); + else +#endif + { +#if !defined(_MSC_VER) && !defined(__MINGW32__) + /* Don't know if this is a libffi bug or not. At least on + Windows with MSVC, function call parameters are *not* + aligned in the same way as structure fields are, they are + only aligned in integer boundaries. + + This doesn't do any harm for cdecl functions and closures, + since the caller cleans up the stack, but it is wrong for + stdcall functions where the callee cleans. + */ + + /* Add any padding if necessary */ + if (((*ptr)->alignment - 1) & bytes) + bytes = ALIGN(bytes, (*ptr)->alignment); + +#endif + bytes += STACK_ARG_SIZE((*ptr)->size); + } +#endif + } + + cif->bytes = bytes; + + /* Perform machine dependent cif processing */ + return ffi_prep_cif_machdep(cif); +} Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/pypy_ffi.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/pypy_ffi.c (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/pypy_ffi.c Fri Mar 19 21:38:17 2010 @@ -1,43 +1,43 @@ -/* This file contains definition from symbols not defined - * in the libffi_msvc directory of CPython. - * most definitions wer copied from the ctypes.c file. - */ - -#include "ffi.h" -#include -#include - -typedef struct { char c; long long x; } s_long_long; -typedef struct { char c; float x; } s_float; -typedef struct { char c; double x; } s_double; -typedef struct { char c; void *x; } s_void_p; -#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) -#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) -#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) -#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*)) - -/* align and size are bogus for void, but they must not be zero */ -ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; - -ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 }; -ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 }; - -ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 }; -ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 }; - -ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 }; -ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 }; - -ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 }; -ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; - -ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; -ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; - -ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; - -void ffi_fatalerror(const char* msg) { - fprintf(stderr, "%s\\n", msg); - abort(); -} - +/* This file contains definition from symbols not defined + * in the libffi_msvc directory of CPython. + * most definitions wer copied from the ctypes.c file. + */ + +#include "ffi.h" +#include +#include + +typedef struct { char c; long long x; } s_long_long; +typedef struct { char c; float x; } s_float; +typedef struct { char c; double x; } s_double; +typedef struct { char c; void *x; } s_void_p; +#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) +#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) +#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) +#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void*)) + +/* align and size are bogus for void, but they must not be zero */ +ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; + +ffi_type ffi_type_uint8 = { 1, 1, FFI_TYPE_UINT8 }; +ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 }; + +ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 }; +ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 }; + +ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 }; +ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 }; + +ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 }; +ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; + +ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; +ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; + +ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; + +void ffi_fatalerror(const char* msg) { + fprintf(stderr, "%s\\n", msg); + abort(); +} + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/types.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/types.c (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/types.c Fri Mar 19 21:38:17 2010 @@ -1,104 +1,104 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Predefined ffi_types needed by libffi. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -/* Type definitions */ - -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - -#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ - || defined IA64 - -FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); - -#else - -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); - -#endif - -#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined SH - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#else - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); - -#endif - - -#if defined X86 || defined X86_WIN32 || defined M68K - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined SPARC - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -#ifdef SPARC64 -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -#else -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); -#endif - -#elif defined X86_64 - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); - -#else - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); - -#endif - +/* ----------------------------------------------------------------------- + types.c - Copyright (c) 1996, 1998 Red Hat, Inc. + + Predefined ffi_types needed by libffi. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include + +/* Type definitions */ + +#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } +#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } + +/* Size and alignment are fake here. They must not be 0. */ +FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); + +FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); +FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); +FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); +FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); +FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); +FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); +FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); + +#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ + || defined IA64 + +FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); + +#else + +FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); + +#endif + +#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); + +#elif defined SH + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); + +#else + +FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); +FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); + +#endif + + +#if defined X86 || defined X86_WIN32 || defined M68K + +FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); + +#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN + +FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); + +#elif defined SPARC + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +#ifdef SPARC64 +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); +#else +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); +#endif + +#elif defined X86_64 + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); + +#else + +FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); +FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); + +#endif + Modified: pypy/trunk/pypy/translator/c/src/libffi_msvc/win32.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/libffi_msvc/win32.c (original) +++ pypy/trunk/pypy/translator/c/src/libffi_msvc/win32.c Fri Mar 19 21:38:17 2010 @@ -1,267 +1,267 @@ -/* ----------------------------------------------------------------------- - win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. - Copyright (c) 2001 John Beniton - Copyright (c) 2002 Ranjit Mathew - - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* theller: almost verbatim translation from gas syntax to MSVC inline - assembler code. */ - -/* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the - difference of the stack pointer before and after the function call. If - everything is ok, zero is returned. If stdcall functions are passed the - wrong number of arguments, the difference will be nonzero. */ - -#include -#include - -__declspec(naked) int -ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */ - extended_cif *ecif, /* 12 */ - unsigned bytes, /* 16 */ - unsigned flags, /* 20 */ - unsigned *rvalue, /* 24 */ - void (*fn)()) /* 28 */ -{ - _asm { - push ebp - mov ebp, esp - - push esi // NEW: this register must be preserved across function calls -// XXX SAVE ESP NOW! - mov esi, esp // save stack pointer before the call - -// Make room for all of the new args. - mov ecx, [ebp+16] - sub esp, ecx // sub esp, bytes - - mov eax, esp - -// Place all of the ffi_prep_args in position - push [ebp + 12] // ecif - push eax - call [ebp + 8] // prepfunc - -// Return stack to previous state and call the function - add esp, 8 -// FIXME: Align the stack to a 128-bit boundary to avoid -// potential performance hits. - call [ebp + 28] -// Remove the space we pushed for the args - mov ecx, [ebp + 16] - add esp, ecx - -// XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE! - sub esi, esp - -// Load %ecx with the return type code - mov ecx, [ebp + 20] - -// If the return value pointer is NULL, assume no return value. -/* - Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, - otherwise only one BYTE will be compared (instead of a DWORD)! - */ - cmp DWORD PTR [ebp + 24], 0 - jne sc_retint - -// Even if there is no space for the return value, we are -// obliged to handle floating-point values. - cmp ecx, FFI_TYPE_FLOAT - jne sc_noretval -// fstp %st(0) - fstp st(0) - - jmp sc_epilogue - -sc_retint: - cmp ecx, FFI_TYPE_INT - jne sc_retfloat -// # Load %ecx with the pointer to storage for the return value - mov ecx, [ebp + 24] - mov [ecx + 0], eax - jmp sc_epilogue - -sc_retfloat: - cmp ecx, FFI_TYPE_FLOAT - jne sc_retdouble -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstps (%ecx) - fstp DWORD PTR [ecx] - jmp sc_epilogue - -sc_retdouble: - cmp ecx, FFI_TYPE_DOUBLE - jne sc_retlongdouble -// movl 24(%ebp),%ecx - mov ecx, [ebp+24] - fstp QWORD PTR [ecx] - jmp sc_epilogue - - jmp sc_retlongdouble // avoid warning about unused label -sc_retlongdouble: - cmp ecx, FFI_TYPE_LONGDOUBLE - jne sc_retint64 -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstpt (%ecx) - fstp QWORD PTR [ecx] /* XXX ??? */ - jmp sc_epilogue - -sc_retint64: - cmp ecx, FFI_TYPE_SINT64 - jne sc_retstruct -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] - mov [ecx+0], eax - mov [ecx+4], edx - -sc_retstruct: -// Nothing to do! - -sc_noretval: -sc_epilogue: - mov eax, esi - pop esi // NEW restore: must be preserved across function calls - mov esp, ebp - pop ebp - ret - } -} - -__declspec(naked) int -ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */ - extended_cif *ecif, /* 12 */ - unsigned bytes, /* 16 */ - unsigned flags, /* 20 */ - unsigned *rvalue, /* 24 */ - void (*fn)()) /* 28 */ -{ - _asm { - push ebp - mov ebp, esp - - push esi // NEW: this register must be preserved across function calls - -// XXX SAVE ESP NOW! - mov esi, esp - -// Make room for all of the new args. - mov ecx, [ebp+16] - sub esp, ecx - - mov eax, esp - -// Place all of the ffi_prep_args in position - push [ebp + 12] // ecif - push eax - call [ebp + 8] // prepfunc - -// Return stack to previous state and call the function - add esp, 8 -// FIXME: Align the stack to a 128-bit boundary to avoid -// potential performance hits. - call [ebp + 28] -// stdcall functions pop arguments off the stack themselves - -// XXX IS ESP NOW THE SAME AS BEFORE? - sub esi, esp - -// Load %ecx with the return type code - mov ecx, [ebp + 20] - -// If the return value pointer is NULL, assume no return value. -/* - Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, - otherwise only one BYTE will be compared (instead of a DWORD)! - */ - cmp DWORD PTR [ebp + 24], 0 - jne sc_retint - -// Even if there is no space for the return value, we are -// obliged to handle floating-point values. - cmp ecx, FFI_TYPE_FLOAT - jne sc_noretval -// fstp %st(0) - fstp st(0) - - jmp sc_epilogue - -sc_retint: - cmp ecx, FFI_TYPE_INT - jne sc_retfloat -// # Load %ecx with the pointer to storage for the return value - mov ecx, [ebp + 24] - mov [ecx + 0], eax - jmp sc_epilogue - -sc_retfloat: - cmp ecx, FFI_TYPE_FLOAT - jne sc_retdouble -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstps (%ecx) - fstp DWORD PTR [ecx] - jmp sc_epilogue - -sc_retdouble: - cmp ecx, FFI_TYPE_DOUBLE - jne sc_retlongdouble -// movl 24(%ebp),%ecx - mov ecx, [ebp+24] - fstp QWORD PTR [ecx] - jmp sc_epilogue - - jmp sc_retlongdouble // avoid warning about unused label -sc_retlongdouble: - cmp ecx, FFI_TYPE_LONGDOUBLE - jne sc_retint64 -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] -// fstpt (%ecx) - fstp QWORD PTR [ecx] /* XXX ??? */ - jmp sc_epilogue - -sc_retint64: - cmp ecx, FFI_TYPE_SINT64 - jne sc_retstruct -// Load %ecx with the pointer to storage for the return value - mov ecx, [ebp+24] - mov [ecx+0], eax - mov [ecx+4], edx - -sc_retstruct: -// Nothing to do! - -sc_noretval: -sc_epilogue: - mov eax, esi - pop esi // NEW restore: must be preserved across function calls - mov esp, ebp - pop ebp - ret - } -} +/* ----------------------------------------------------------------------- + win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + + + X86 Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +/* theller: almost verbatim translation from gas syntax to MSVC inline + assembler code. */ + +/* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the + difference of the stack pointer before and after the function call. If + everything is ok, zero is returned. If stdcall functions are passed the + wrong number of arguments, the difference will be nonzero. */ + +#include +#include + +__declspec(naked) int +ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */ + extended_cif *ecif, /* 12 */ + unsigned bytes, /* 16 */ + unsigned flags, /* 20 */ + unsigned *rvalue, /* 24 */ + void (*fn)()) /* 28 */ +{ + _asm { + push ebp + mov ebp, esp + + push esi // NEW: this register must be preserved across function calls +// XXX SAVE ESP NOW! + mov esi, esp // save stack pointer before the call + +// Make room for all of the new args. + mov ecx, [ebp+16] + sub esp, ecx // sub esp, bytes + + mov eax, esp + +// Place all of the ffi_prep_args in position + push [ebp + 12] // ecif + push eax + call [ebp + 8] // prepfunc + +// Return stack to previous state and call the function + add esp, 8 +// FIXME: Align the stack to a 128-bit boundary to avoid +// potential performance hits. + call [ebp + 28] +// Remove the space we pushed for the args + mov ecx, [ebp + 16] + add esp, ecx + +// XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE! + sub esi, esp + +// Load %ecx with the return type code + mov ecx, [ebp + 20] + +// If the return value pointer is NULL, assume no return value. +/* + Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, + otherwise only one BYTE will be compared (instead of a DWORD)! + */ + cmp DWORD PTR [ebp + 24], 0 + jne sc_retint + +// Even if there is no space for the return value, we are +// obliged to handle floating-point values. + cmp ecx, FFI_TYPE_FLOAT + jne sc_noretval +// fstp %st(0) + fstp st(0) + + jmp sc_epilogue + +sc_retint: + cmp ecx, FFI_TYPE_INT + jne sc_retfloat +// # Load %ecx with the pointer to storage for the return value + mov ecx, [ebp + 24] + mov [ecx + 0], eax + jmp sc_epilogue + +sc_retfloat: + cmp ecx, FFI_TYPE_FLOAT + jne sc_retdouble +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstps (%ecx) + fstp DWORD PTR [ecx] + jmp sc_epilogue + +sc_retdouble: + cmp ecx, FFI_TYPE_DOUBLE + jne sc_retlongdouble +// movl 24(%ebp),%ecx + mov ecx, [ebp+24] + fstp QWORD PTR [ecx] + jmp sc_epilogue + + jmp sc_retlongdouble // avoid warning about unused label +sc_retlongdouble: + cmp ecx, FFI_TYPE_LONGDOUBLE + jne sc_retint64 +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstpt (%ecx) + fstp QWORD PTR [ecx] /* XXX ??? */ + jmp sc_epilogue + +sc_retint64: + cmp ecx, FFI_TYPE_SINT64 + jne sc_retstruct +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] + mov [ecx+0], eax + mov [ecx+4], edx + +sc_retstruct: +// Nothing to do! + +sc_noretval: +sc_epilogue: + mov eax, esi + pop esi // NEW restore: must be preserved across function calls + mov esp, ebp + pop ebp + ret + } +} + +__declspec(naked) int +ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */ + extended_cif *ecif, /* 12 */ + unsigned bytes, /* 16 */ + unsigned flags, /* 20 */ + unsigned *rvalue, /* 24 */ + void (*fn)()) /* 28 */ +{ + _asm { + push ebp + mov ebp, esp + + push esi // NEW: this register must be preserved across function calls + +// XXX SAVE ESP NOW! + mov esi, esp + +// Make room for all of the new args. + mov ecx, [ebp+16] + sub esp, ecx + + mov eax, esp + +// Place all of the ffi_prep_args in position + push [ebp + 12] // ecif + push eax + call [ebp + 8] // prepfunc + +// Return stack to previous state and call the function + add esp, 8 +// FIXME: Align the stack to a 128-bit boundary to avoid +// potential performance hits. + call [ebp + 28] +// stdcall functions pop arguments off the stack themselves + +// XXX IS ESP NOW THE SAME AS BEFORE? + sub esi, esp + +// Load %ecx with the return type code + mov ecx, [ebp + 20] + +// If the return value pointer is NULL, assume no return value. +/* + Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction, + otherwise only one BYTE will be compared (instead of a DWORD)! + */ + cmp DWORD PTR [ebp + 24], 0 + jne sc_retint + +// Even if there is no space for the return value, we are +// obliged to handle floating-point values. + cmp ecx, FFI_TYPE_FLOAT + jne sc_noretval +// fstp %st(0) + fstp st(0) + + jmp sc_epilogue + +sc_retint: + cmp ecx, FFI_TYPE_INT + jne sc_retfloat +// # Load %ecx with the pointer to storage for the return value + mov ecx, [ebp + 24] + mov [ecx + 0], eax + jmp sc_epilogue + +sc_retfloat: + cmp ecx, FFI_TYPE_FLOAT + jne sc_retdouble +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstps (%ecx) + fstp DWORD PTR [ecx] + jmp sc_epilogue + +sc_retdouble: + cmp ecx, FFI_TYPE_DOUBLE + jne sc_retlongdouble +// movl 24(%ebp),%ecx + mov ecx, [ebp+24] + fstp QWORD PTR [ecx] + jmp sc_epilogue + + jmp sc_retlongdouble // avoid warning about unused label +sc_retlongdouble: + cmp ecx, FFI_TYPE_LONGDOUBLE + jne sc_retint64 +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] +// fstpt (%ecx) + fstp QWORD PTR [ecx] /* XXX ??? */ + jmp sc_epilogue + +sc_retint64: + cmp ecx, FFI_TYPE_SINT64 + jne sc_retstruct +// Load %ecx with the pointer to storage for the return value + mov ecx, [ebp+24] + mov [ecx+0], eax + mov [ecx+4], edx + +sc_retstruct: +// Nothing to do! + +sc_noretval: +sc_epilogue: + mov eax, esi + pop esi // NEW restore: must be preserved across function calls + mov esp, ebp + pop ebp + ret + } +} From afa at codespeak.net Fri Mar 19 22:24:19 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 19 Mar 2010 22:24:19 +0100 (CET) Subject: [pypy-svn] r72429 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100319212419.503E0282BD4@codespeak.net> Author: afa Date: Fri Mar 19 22:24:17 2010 New Revision: 72429 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/pythonrun.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Fix tests on Linux. the "#define long int" is a hack, but I don't know how to do it otherwise Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Fri Mar 19 22:24:17 2010 @@ -61,7 +61,9 @@ structindex[name] = len(structindex) structmembers = '\n'.join(members) struct_declaration_code = """\ + #define const /* cheat */ #include + #define long int /* cheat */ struct PyPyAPI { %(members)s } _pypyAPI; Modified: pypy/trunk/pypy/module/cpyext/pythonrun.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/pythonrun.py (original) +++ pypy/trunk/pypy/module/cpyext/pythonrun.py Fri Mar 19 22:24:17 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api - at cpython_api([], lltype.Signed) + at cpython_api([], rffi.INT) def Py_IsInitialized(space): return 1 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Fri Mar 19 22:24:17 2010 @@ -7,6 +7,8 @@ from pypy.translator import platform from pypy.module.cpyext import api +import sys + class TestApi(): def test_signature(self): assert 'Py_InitModule' in api.FUNCTIONS @@ -14,14 +16,14 @@ rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] assert api.FUNCTIONS['Py_InitModule'].restype == lltype.Void -def compile_module(name, code, libraries=()): +def compile_module(name, code, **kwds): include_dir = py.path.local(autopath.pypydir).join( 'module', 'cpyext', 'include') eci = ExternalCompilationInfo( separate_module_sources=[code], export_symbols=['init%s' % (name,)], include_dirs=[include_dir], - libraries=libraries, + **kwds ) eci = eci.convert_sources_to_files() soname = platform.platform.compile( @@ -42,7 +44,12 @@ %(init)s } """ % dict(name=name, init=init, body=body) - mod = compile_module(name, code, libraries=[self.api_library]) + if sys.platform == 'win32': + libraries = [self.api_library] + mod = compile_module(name, code, libraries=libraries) + else: + libraries = [str(self.api_library+'.so')] + mod = compile_module(name, code, link_files=libraries) import ctypes initfunc = ctypes.CDLL(mod)['init%s' % (name,)] initfunc() From afa at codespeak.net Sat Mar 20 00:11:47 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 20 Mar 2010 00:11:47 +0100 (CET) Subject: [pypy-svn] r72431 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100319231147.E84D3282BD4@codespeak.net> Author: afa Date: Sat Mar 20 00:11:46 2010 New Revision: 72431 Added: pypy/trunk/pypy/module/cpyext/methodobject.py (contents, props changed) Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/floatobject.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: More progress, the C method is now is now really called. next step: implement the Refence Counted wrapper, a.k.a PyObject*. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 00:11:46 2010 @@ -31,20 +31,29 @@ return decorate def cpython_struct(name, fields): - setattr(CConfig, name, rffi_platform.Struct(name, fields)) + configname = name.replace(' ', '__') + setattr(CConfig, configname, rffi_platform.Struct(name, fields)) forward = lltype.ForwardReference() - TYPES[name] = forward + TYPES[configname] = forward return forward FUNCTIONS = {} TYPES = {} -PyObject = cpython_struct('PyObject', []) +PyObject = lltype.Ptr(cpython_struct('struct _object', [])) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): TYPES[name].become(TYPE) +def make_ref(w_obj): + return lltype.nullptr(PyObject.TO) # XXX for the moment + +def from_ref(space, ref): + if not ref: + return space.w_None # XXX for the moment, should be an exception + assert False + #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 00:11:46 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref - at cpython_api([lltype.Float], lltype.Ptr(PyObject)) + at cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): - return space.wrap(value) + return make_ref(space.wrap(value)) Added: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sat Mar 20 00:11:46 2010 @@ -0,0 +1,33 @@ +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.gateway import ObjSpace, W_Root +from pypy.interpreter.argument import Arguments +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import PyObject, from_ref + +class W_PyCFunctionObject(Wrappable): + def __init__(self, ml, w_self, w_modname): + self.ml = ml + self.w_self = w_self + self.w_modname = w_modname + + at unwrap_spec(ObjSpace, W_Root, Arguments) +def cfunction_descr_call(space, w_self, __args__): + self = space.interp_w(W_PyCFunctionObject, w_self) + args_w, kw_w = __args__.unpack() + null = lltype.nullptr(PyObject.TO) # XXX for the moment + + # Call the C function + result = self.ml.c_ml_meth(null, null) + ret = from_ref(space, result) + # XXX result.decref() + return ret + +W_PyCFunctionObject.typedef = TypeDef( + 'builtin_function_or_method', + __call__ = interp2app(cfunction_descr_call), + ) + +def PyCFunction_NewEx(space, ml, w_self, w_modname): + return space.wrap(W_PyCFunctionObject(ml, w_self, w_modname)) Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sat Mar 20 00:11:46 2010 @@ -1,10 +1,15 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, cpython_struct +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject from pypy.interpreter.module import Module +from pypy.module.cpyext.methodobject import PyCFunction_NewEx + +PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) PyMethodDef = cpython_struct( 'PyMethodDef', [('ml_name', rffi.CCHARP), + ('ml_meth', PyCFunction), + ('ml_flags', rffi.INT), ]) def PyImport_AddModule(space, name): @@ -17,16 +22,19 @@ @cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) def Py_InitModule(space, name, methods): - name = rffi.charp2str(name) - w_mod = PyImport_AddModule(space, name) + modname = rffi.charp2str(name) + w_mod = PyImport_AddModule(space, modname) methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) if methods: i = 0 while True: method = methods[i] if not method.c_ml_name: break + methodname = rffi.charp2str(method.c_ml_name) + flags = method.c_ml_flags + w_function = PyCFunction_NewEx(space, method, None, modname) space.setattr(w_mod, space.wrap(methodname), - space.w_None) # XXX for the moment + w_function) i = i + 1 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 00:11:46 2010 @@ -95,4 +95,5 @@ module = self.import_module(name='foo', init=init, body=body) assert 'foo' in sys.modules assert 'return_pi' in dir(module) - assert module.return_pi is None # XXX for the moment + assert module.return_pi is not None + assert module.return_pi() is None # XXX for the moment From afa at codespeak.net Sat Mar 20 01:10:19 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 20 Mar 2010 01:10:19 +0100 (CET) Subject: [pypy-svn] r72432 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100320001019.E088C282BD4@codespeak.net> Author: afa Date: Sat Mar 20 01:10:17 2010 New Revision: 72432 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: when testing on top of CPython, rename all symbols to avoid name clashes Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 01:10:17 2010 @@ -4,16 +4,19 @@ from pypy.rpython.annlowlevel import llhelper from pypy.translator.c.database import LowLevelDatabase from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.tool.udir import udir from pypy.translator import platform import py, autopath -include_dir = py.path.local(autopath.pypydir).join( - 'module', 'cpyext', 'include') +include_dirs = [ + py.path.local(autopath.pypydir).join('module', 'cpyext', 'include'), + udir, + ] class CConfig: _compilation_info_ = ExternalCompilationInfo( - include_dirs=[include_dir], + include_dirs=include_dirs, includes=['Python.h'] ) @@ -57,11 +60,32 @@ #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions -def build_bridge(space): +def build_bridge(space, rename=True): db = LowLevelDatabase() + export_symbols = list(FUNCTIONS) + structindex = {} + prologue = """\ + #define const /* cheat */ + #include + #define long int /* cheat */ + """ + if rename: + pypy_rename = [] + export_symbols = [] + for name in FUNCTIONS: + newname = name.replace('Py', 'PyPy') + pypy_rename.append('#define %s %s' % (name, newname)) + export_symbols.append(newname) + pypy_rename_h = udir.join('pypy_rename.h') + pypy_rename_h.write('\n'.join(pypy_rename)) + + prologue = """\ + #include /* avoid symbol clashes */ + """ + prologue + # Structure declaration code members = [] for name, func in FUNCTIONS.iteritems(): @@ -70,9 +94,6 @@ structindex[name] = len(structindex) structmembers = '\n'.join(members) struct_declaration_code = """\ - #define const /* cheat */ - #include - #define long int /* cheat */ struct PyPyAPI { %(members)s } _pypyAPI; @@ -94,13 +115,16 @@ body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) - code = struct_declaration_code + '\n' + '\n'.join(functions) + code = (prologue + + struct_declaration_code + + '\n' + + '\n'.join(functions)) # Build code and get pointer to the structure eci = ExternalCompilationInfo( - include_dirs=[include_dir], + include_dirs=include_dirs, separate_module_sources=[code], - export_symbols=['pypyAPI'] + list(FUNCTIONS), + export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() modulename = platform.platform.compile( Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 01:10:17 2010 @@ -1,5 +1,3 @@ -import py, autopath - from pypy.conftest import gettestobjspace from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype @@ -7,6 +5,7 @@ from pypy.translator import platform from pypy.module.cpyext import api +import py, autopath import sys class TestApi(): @@ -16,13 +15,11 @@ rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] assert api.FUNCTIONS['Py_InitModule'].restype == lltype.Void -def compile_module(name, code, **kwds): - include_dir = py.path.local(autopath.pypydir).join( - 'module', 'cpyext', 'include') +def compile_module(modname, code, **kwds): eci = ExternalCompilationInfo( separate_module_sources=[code], - export_symbols=['init%s' % (name,)], - include_dirs=[include_dir], + export_symbols=['init%s' % (modname,)], + include_dirs=api.include_dirs, **kwds ) eci = eci.convert_sources_to_files() @@ -33,10 +30,11 @@ class AppTestCpythonExtension: def setup_class(cls): - cls.api_library = api.build_bridge(cls.space) + cls.api_library = api.build_bridge(cls.space, rename=True) def import_module(self, name, init, body=''): code = """ + #include #include %(body)s From xoraxax at codespeak.net Sat Mar 20 05:23:00 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 05:23:00 +0100 (CET) Subject: [pypy-svn] r72433 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320042300.45E6D282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 05:22:58 2010 New Revision: 72433 Added: pypy/trunk/pypy/module/cpyext/state.py Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/floatobject.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: After hours of fighting with ll2ctypes (probably should be implemented differently anyway with Addresses - are those hashable?), here is PyObject support for cpyext. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 05:22:58 2010 @@ -1,13 +1,8 @@ from pypy.interpreter.mixedmodule import MixedModule from pypy.rlib.objectmodel import we_are_translated import pypy.module.cpyext.api +from pypy.module.cpyext.state import State -class State: - def __init__(self, space): - if not we_are_translated(): - self.api_lib = str(api.build_bridge(space)) - else: - XXX # build an import library when translating pypy. class Module(MixedModule): interpleveldefs = { @@ -30,5 +25,4 @@ import pypy.module.cpyext.floatobject import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun -from pypy.module.cpyext import api api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 05:22:58 2010 @@ -1,3 +1,7 @@ +import py +import autopath +import ctypes + from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.tool import rffi_platform from pypy.rpython.lltypesystem import ll2ctypes @@ -6,8 +10,8 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.tool.udir import udir from pypy.translator import platform +from pypy.module.cpyext.state import State -import py, autopath include_dirs = [ py.path.local(autopath.pypydir).join('module', 'cpyext', 'include'), @@ -29,7 +33,9 @@ def cpython_api(argtypes, restype): def decorate(func): - FUNCTIONS[func.func_name] = ApiFunction(argtypes, restype, func) + api_function = ApiFunction(argtypes, restype, func) + FUNCTIONS[func.func_name] = api_function + func.api_func = api_function return func return decorate @@ -43,19 +49,34 @@ FUNCTIONS = {} TYPES = {} -PyObject = lltype.Ptr(cpython_struct('struct _object', [])) +# It is important that these PyObjects are allocated in a raw fashion +# Thus we cannot save a forward pointer to the wrapped object +# So we need a forward and backward mapping in our State instance +PyObject = lltype.Ptr(cpython_struct('struct _object', [("refcnt", lltype.Signed)])) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): TYPES[name].become(TYPE) -def make_ref(w_obj): - return lltype.nullptr(PyObject.TO) # XXX for the moment +def make_ref(space, w_obj): + state = space.fromcache(State) + py_obj = state.py_objects_w2r.get(w_obj) + if py_obj is None: + py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) + ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value + py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) + state.py_objects_w2r[w_obj] = py_obj + state.py_objects_r2w[ptr] = w_obj + return py_obj def from_ref(space, ref): + state = space.fromcache(State) if not ref: - return space.w_None # XXX for the moment, should be an exception - assert False + raise RuntimeError("Null pointer dereference!") + ptr = ctypes.addressof(ref._obj._storage) + obj = state.py_objects_r2w[ptr] + return obj #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call @@ -138,7 +159,16 @@ def make_wrapper(callable): def wrapper(*args): - return callable(space, *args) + boxed_args = [] + # XXX use unrolling_iterable here + for typ, arg in zip(callable.api_func.argtypes, args): + if typ is PyObject: + arg = from_ref(space, arg) + boxed_args.append(arg) + retval = callable(space, *boxed_args) + if callable.api_func.restype is PyObject: + retval = make_ref(space, retval) + return retval return wrapper # implement structure initialization code Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 05:22:58 2010 @@ -3,4 +3,4 @@ @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): - return make_ref(space.wrap(value)) + return space.wrap(value) Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 05:22:58 2010 @@ -2,7 +2,7 @@ #define Py_PYTHON_H typedef struct _object { - int __dummy; + long refcnt; } PyObject; #include Added: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/state.py Sat Mar 20 05:22:58 2010 @@ -0,0 +1,14 @@ +from pypy.rlib.objectmodel import we_are_translated +from pypy.lib.identity_dict import identity_dict + + +class State: + def __init__(self, space): + from pypy.module.cpyext import api + self.py_objects_w2r = identity_dict() # w_obj -> raw PyObject + self.py_objects_r2w = {} # addr of raw PyObject -> w_obj + if not we_are_translated(): + self.api_lib = str(api.build_bridge(space)) + else: + XXX # build an import library when translating pypy. + Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 05:22:58 2010 @@ -94,4 +94,4 @@ assert 'foo' in sys.modules assert 'return_pi' in dir(module) assert module.return_pi is not None - assert module.return_pi() is None # XXX for the moment + assert module.return_pi() == 3.14 From xoraxax at codespeak.net Sat Mar 20 06:17:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 06:17:20 +0100 (CET) Subject: [pypy-svn] r72434 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320051720.DFCB1282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 06:17:18 2010 New Revision: 72434 Added: pypy/trunk/pypy/module/cpyext/macros.py Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/state.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Added new test and Py_None support. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 06:17:18 2010 @@ -14,6 +14,10 @@ def setup_after_space_initialization(self): """NOT_RPYTHON""" state = self.space.fromcache(State) + if not we_are_translated(): + state.api_lib = str(pypy.module.cpyext.api.build_bridge(space)) + else: + XXX # build an import library when translating pypy. def startup(self, space): state = space.fromcache(State) @@ -25,4 +29,5 @@ import pypy.module.cpyext.floatobject import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun +import pypy.module.cpyext.macros api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 06:17:18 2010 @@ -63,6 +63,7 @@ py_obj = state.py_objects_w2r.get(w_obj) if py_obj is None: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + py_obj.c_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) @@ -75,7 +76,10 @@ if not ref: raise RuntimeError("Null pointer dereference!") ptr = ctypes.addressof(ref._obj._storage) - obj = state.py_objects_r2w[ptr] + try: + obj = state.py_objects_r2w[ptr] + except KeyError: + raise RuntimeError("Got invalid reference to a PyObject") return obj #_____________________________________________________ @@ -136,8 +140,12 @@ body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) + global_objects = """ + PyObject *PyPy_None = NULL; + """ code = (prologue + struct_declaration_code + + global_objects + '\n' + '\n'.join(functions)) @@ -156,6 +164,7 @@ import ctypes bridge = ctypes.CDLL(str(modulename)) pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') + Py_NONE = ctypes.c_void_p.in_dll(bridge, 'PyPy_None') def make_wrapper(callable): def wrapper(*args): @@ -176,6 +185,8 @@ pypyAPI[structindex[name]] = ctypes.cast( ll2ctypes.lltype2ctypes(llhelper(func.functype, make_wrapper(func.callable))), ctypes.c_void_p) + Py_NONE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_None)), + ctypes.c_void_p).value return modulename.new(ext='') Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 06:17:18 2010 @@ -4,6 +4,8 @@ typedef struct _object { long refcnt; } PyObject; +extern PyObject *PyPy_None; +#define Py_None PyPy_None #include Added: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/macros.py Sat Mar 20 06:17:18 2010 @@ -0,0 +1,20 @@ +import ctypes + +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.state import State + +# XXX Optimize these functions and put them into macro definitions + at cpython_api([PyObject], lltype.Void) +def Py_DECREF(space, w_obj): + state = space.fromcache(State) + obj = state.py_objects_w2r.get(w_obj) + obj.c_refcnt -= 1 + return + + at cpython_api([PyObject], lltype.Void) +def Py_INCREF(space, w_obj): + state = space.fromcache(State) + obj = state.py_objects_w2r.get(w_obj) + obj.c_refcnt += 1 + return Modified: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/state.py (original) +++ pypy/trunk/pypy/module/cpyext/state.py Sat Mar 20 06:17:18 2010 @@ -4,11 +4,6 @@ class State: def __init__(self, space): - from pypy.module.cpyext import api self.py_objects_w2r = identity_dict() # w_obj -> raw PyObject self.py_objects_r2w = {} # addr of raw PyObject -> w_obj - if not we_are_translated(): - self.api_lib = str(api.build_bridge(space)) - else: - XXX # build an import library when translating pypy. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 06:17:18 2010 @@ -95,3 +95,47 @@ assert 'return_pi' in dir(module) assert module.return_pi is not None assert module.return_pi() == 3.14 + + def test_export_function2(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + static PyObject* my_objects[1]; + static PyObject* foo_cached_pi(PyObject* self, PyObject *args) + { + if (my_objects[0] == NULL) { + my_objects[0] = PyFloat_FromDouble(3.14); + Py_INCREF(my_objects[0]); + } + return my_objects[0]; + } + static PyObject* foo_drop_pi(PyObject* self, PyObject *args) + { + if (my_objects[0] != NULL) { + Py_DECREF(my_objects[0]); + my_objects[0] = NULL; + } + Py_INCREF(Py_None); + return Py_None; + } + static PyObject* foo_retinvalid(PyObject* self, PyObject *args) + { + return (PyObject*)0xAFFEBABE; + } + static PyMethodDef methods[] = { + { "return_pi", foo_cached_pi, METH_NOARGS }, + { "drop_pi", foo_drop_pi, METH_NOARGS }, + { "return_invalid_pointer", foo_retinvalid, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + raises(RuntimeError, module.return_invalid_pointer) + assert module.return_pi() == 3.14 + module.drop_pi() + module.drop_pi() + assert module.return_pi() == 3.14 + assert module.return_pi() == 3.14 From xoraxax at codespeak.net Sat Mar 20 06:41:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 06:41:49 +0100 (CET) Subject: [pypy-svn] r72435 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320054149.09307282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 06:41:48 2010 New Revision: 72435 Modified: pypy/trunk/pypy/module/cpyext/macros.py Log: Add deallocation code. Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sat Mar 20 06:41:48 2010 @@ -10,6 +10,13 @@ state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) obj.c_refcnt -= 1 + if obj.c_refcnt == 0: + del state.py_objects_w2r[w_obj] + ptr = ctypes.addressof(obj._obj._storage) + del state.py_objects_r2w[ptr] + lltype.free(obj) + else: + assert obj.c_refcnt > 0 return @cpython_api([PyObject], lltype.Void) From arigo at codespeak.net Sat Mar 20 09:43:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 09:43:33 +0100 (CET) Subject: [pypy-svn] r72436 - in pypy/branch/kill-python-h/pypy/rlib: . test Message-ID: <20100320084333.7D142282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 09:43:31 2010 New Revision: 72436 Modified: pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py pypy/branch/kill-python-h/pypy/rlib/test/test_rsocket.py Log: Test and fix. Modified: pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/_rsocket_rffi.py Sat Mar 20 09:43:31 2010 @@ -572,4 +572,4 @@ else: socket_strerror_str = os.strerror def gai_strerror_str(errno): - return rffi.charp2str(gai_strerror(self.errno)) + return rffi.charp2str(gai_strerror(errno)) Modified: pypy/branch/kill-python-h/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/branch/kill-python-h/pypy/rlib/test/test_rsocket.py (original) +++ pypy/branch/kill-python-h/pypy/rlib/test/test_rsocket.py Sat Mar 20 09:43:31 2010 @@ -281,7 +281,8 @@ addr.get_port() == 80): found = True assert found, lst - py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', None) + e = py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', None) + assert isinstance(e.value.get_msg(), str) def test_getaddrinfo_codespeak(): lst = getaddrinfo('codespeak.net', None) From arigo at codespeak.net Sat Mar 20 11:39:23 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 11:39:23 +0100 (CET) Subject: [pypy-svn] r72438 - pypy/build/bot2/pypybuildbot Message-ID: <20100320103923.4C34F282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 11:39:22 2010 New Revision: 72438 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Add "tannit" as a buildslave. If everything goes right, we might reorder a bit to give it higher priority than "bigdogvm1". Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Sat Mar 20 11:39:22 2010 @@ -146,7 +146,7 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["cobra", "bigdogvm1"], + "slavenames": ["cobra", "bigdogvm1", "tannit"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'own' @@ -158,19 +158,19 @@ "category": 'mac' }, {"name": APPLVLLINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["bigdogvm1", "tannit"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'applevel' }, {"name": STACKLESSAPPLVLLINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["bigdogvm1", "tannit"], "builddir": STACKLESSAPPLVLLINUX32, "factory": pypyStacklessTranslatedAppLevelTestFactory, "category": 'stackless' }, {"name": OJITLINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["bigdogvm1", "tannit"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'applevel' @@ -188,7 +188,7 @@ "category": 'other' }, {"name" : JITLINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["bigdogvm1", "tannit"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'jit', @@ -206,7 +206,7 @@ 'category' : 'jit', }, {"name": JITONLYLINUX32, - "slavenames": ["bigdogvm1"], + "slavenames": ["tannit", "bigdogvm1"], "builddir": JITONLYLINUX32, "factory": pypyJitOnlyOwnTestFactory, "category": 'own' From arigo at codespeak.net Sat Mar 20 11:46:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 11:46:18 +0100 (CET) Subject: [pypy-svn] r72439 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100320104618.66168282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 11:46:16 2010 New Revision: 72439 Added: pypy/trunk/pypy/module/cpyext/test/conftest.py (contents, props changed) Log: Add a conftest to skip these tests in -A. Added: pypy/trunk/pypy/module/cpyext/test/conftest.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/conftest.py Sat Mar 20 11:46:16 2010 @@ -0,0 +1,8 @@ +import py +from pypy.conftest import option + +class Directory(py.test.collect.Directory): + def collect(self): + if option.runappdirect: + py.test.skip("cannot be run by py.test -A") + return super(Directory, self).collect() From arigo at codespeak.net Sat Mar 20 13:25:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 13:25:05 +0100 (CET) Subject: [pypy-svn] r72440 - pypy/branch/rawffi-64 Message-ID: <20100320122505.2AE89282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 13:25:04 2010 New Revision: 72440 Added: pypy/branch/rawffi-64/ - copied from r72439, pypy/trunk/ Log: A branch in which to finish the 64-bit support for rawffi. From arigo at codespeak.net Sat Mar 20 13:25:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 13:25:29 +0100 (CET) Subject: [pypy-svn] r72441 - in pypy/branch/rawffi-64/pypy/rlib: . test Message-ID: <20100320122529.92BF0282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 13:25:28 2010 New Revision: 72441 Modified: pypy/branch/rawffi-64/pypy/rlib/libffi.py pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py Log: The libffi.py side of things. Modified: pypy/branch/rawffi-64/pypy/rlib/libffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/rlib/libffi.py (original) +++ pypy/branch/rawffi-64/pypy/rlib/libffi.py Sat Mar 20 13:25:28 2010 @@ -366,13 +366,26 @@ CALLBACK_TP, rffi.VOIDP], rffi.INT) -def make_struct_ffitype(size, aligment): - tp = lltype.malloc(FFI_TYPE_P.TO, flavor='raw') - tp.c_type = FFI_TYPE_STRUCT - tp.c_size = rffi.cast(rffi.SIZE_T, size) - tp.c_alignment = rffi.cast(rffi.USHORT, aligment) - tp.c_elements = lltype.nullptr(FFI_TYPE_PP.TO) - return tp +FFI_STRUCT_P = lltype.Ptr(lltype.Struct('FFI_STRUCT', + ('ffistruct', FFI_TYPE_P.TO), + ('members', lltype.Array(FFI_TYPE_P)))) + +def make_struct_ffitype_e(size, aligment, field_types): + """Compute the type of a structure. Returns a FFI_STRUCT_P out of + which the 'ffistruct' member is a regular FFI_TYPE. + """ + tpe = lltype.malloc(FFI_STRUCT_P.TO, len(field_types)+1, flavor='raw') + tpe.ffistruct.c_type = FFI_TYPE_STRUCT + tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size) + tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment) + tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP, + lltype.direct_arrayitems(tpe.members)) + n = 0 + while n < len(field_types): + tpe.members[n] = field_types[n] + n += 1 + tpe.members[n] = lltype.nullptr(FFI_TYPE_P.TO) + return tpe def cast_type_to_ffitype(tp): """ This function returns ffi representation of rpython type tp Modified: pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py (original) +++ pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py Sat Mar 20 13:25:28 2010 @@ -233,19 +233,27 @@ del libm assert not ALLOCATED - def test_make_struct_fftiype(self): - tp = make_struct_ffitype(6, 2) - assert tp.c_type == FFI_TYPE_STRUCT - assert tp.c_size == 6 - assert tp.c_alignment == 2 - lltype.free(tp, flavor='raw') + def test_make_struct_ffitype_e(self): + tpe = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar]) + assert tpe.ffistruct.c_type == FFI_TYPE_STRUCT + assert tpe.ffistruct.c_size == 16 + assert tpe.ffistruct.c_alignment == 4 + assert tpe.ffistruct.c_elements[0] == ffi_type_pointer + assert tpe.ffistruct.c_elements[1] == ffi_type_uchar + assert not tpe.ffistruct.c_elements[2] + lltype.free(tpe, flavor='raw') + + def test_nested_struct_elements(self): + tpe2 = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar]) + tp2 = tpe2.ffistruct + tpe = make_struct_ffitype_e(32, 4, [tp2, ffi_type_schar]) + assert tpe.ffistruct.c_elements[0] == tp2 + assert tpe.ffistruct.c_elements[1] == ffi_type_schar + assert not tpe.ffistruct.c_elements[2] + lltype.free(tpe, flavor='raw') + lltype.free(tpe2, flavor='raw') def test_struct_by_val(self): - import platform - if platform.machine() == 'x86_64': - py.test.skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import platform from pypy.tool.udir import udir @@ -277,9 +285,9 @@ slong = cast_type_to_ffitype(rffi.LONG) size = slong.c_size*2 alignment = slong.c_alignment - tp = make_struct_ffitype(size, alignment) + tpe = make_struct_ffitype_e(size, alignment, [slong, slong]) - sum_x_y = lib.getrawpointer('sum_x_y', [tp], slong) + sum_x_y = lib.getrawpointer('sum_x_y', [tpe.ffistruct], slong) buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw') buffer[0] = 200 @@ -291,17 +299,12 @@ lltype.free(buffer, flavor='raw') del sum_x_y - lltype.free(tp, flavor='raw') + lltype.free(tpe, flavor='raw') del lib assert not ALLOCATED def test_ret_struct_val(self): - import platform - if platform.machine() == 'x86_64': - py.test.skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import platform from pypy.tool.udir import udir @@ -337,10 +340,10 @@ size = ffi_type_sshort.c_size*2 alignment = ffi_type_sshort.c_alignment - tp = make_struct_ffitype(size, alignment) + tpe = make_struct_ffitype_e(size, alignment, [ffi_type_sshort]*2) give = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort], - tp) + tpe.ffistruct) inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw') inbuffer[0] = rffi.cast(rffi.SHORT, 40) inbuffer[1] = rffi.cast(rffi.SHORT, 72) @@ -354,7 +357,7 @@ assert outbuffer[0] == 40 assert outbuffer[1] == 72 - perturb = lib.getrawpointer('perturb', [tp], tp) + perturb = lib.getrawpointer('perturb', [tpe.ffistruct], tpe.ffistruct) inbuffer[0] = rffi.cast(rffi.SHORT, 7) inbuffer[1] = rffi.cast(rffi.SHORT, 11) @@ -372,7 +375,7 @@ lltype.free(inbuffer, flavor='raw') del give del perturb - lltype.free(tp, flavor='raw') + lltype.free(tpe, flavor='raw') del lib assert not ALLOCATED From xoraxax at codespeak.net Sat Mar 20 14:10:27 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 14:10:27 +0100 (CET) Subject: [pypy-svn] r72442 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320131027.BDE9A282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 14:10:26 2010 New Revision: 72442 Added: pypy/trunk/pypy/module/cpyext/TODO Log: Added todo list for this module. Added: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/TODO Sat Mar 20 14:10:26 2010 @@ -0,0 +1,3 @@ + - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject + - Add exceptions + From jandem at codespeak.net Sat Mar 20 14:11:13 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 14:11:13 +0100 (CET) Subject: [pypy-svn] r72443 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100320131113.CCA9C282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 14:11:11 2010 New Revision: 72443 Added: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Modified: pypy/trunk/pypy/module/cpyext/floatobject.py Log: add floatobject tests and PyFloat_AsDouble Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 14:11:11 2010 @@ -4,3 +4,7 @@ @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): return space.wrap(value) + + at cpython_api([PyObject], lltype.Float) +def PyFloat_AsDouble(space, w_float): + return 10.0 #XXX: for now Added: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 14:11:11 2010 @@ -0,0 +1,74 @@ +from pypy.conftest import gettestobjspace +from pypy.interpreter.error import OperationError +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.translator.tool.cbuild import ExternalCompilationInfo +from pypy.translator import platform +from pypy.module.cpyext import api +from test_cpyext import compile_module + +import py, autopath +import sys + +class AppTestFloatObject: + def setup_class(cls): + cls.api_library = api.build_bridge(cls.space, rename=True) + + def setup_method(self, func): + self.w_import_module = self.space.wrap(self.import_module) + + def teardown_method(self, func): + try: + self.space.delitem(self.space.sys.get('modules'), + self.space.wrap('foo')) + except OperationError: + pass + + def import_module(self, name, init, body=''): + code = """ + #include + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + if sys.platform == 'win32': + libraries = [self.api_library] + mod = compile_module(name, code, libraries=libraries) + else: + libraries = [str(self.api_library+'.so')] + mod = compile_module(name, code, link_files=libraries) + import ctypes + initfunc = ctypes.CDLL(mod)['init%s' % (name,)] + initfunc() + return self.space.getitem( + self.space.sys.get('modules'), + self.space.wrap(name)) + + def test_floatobject(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + PyObject* foo_FromDouble(PyObject* self, PyObject *args) + { + return PyFloat_FromDouble(3.14); + } + double foo_AsDouble(PyObject* self, PyObject *args) + { + PyObject* pi = PyFloat_FromDouble(3.14); + return PyFloat_AsDouble(pi); + } + static PyMethodDef methods[] = { + { "FromDouble", foo_FromDouble, METH_NOARGS }, + { "AsDouble", foo_AsDouble, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert 'foo' in sys.modules + assert module.FromDouble() == 3.14 + assert module.AsDouble() == 3.14 From jandem at codespeak.net Sat Mar 20 14:12:57 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 14:12:57 +0100 (CET) Subject: [pypy-svn] r72444 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320131257.CA506282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 14:12:56 2010 New Revision: 72444 Modified: pypy/trunk/pypy/module/cpyext/floatobject.py Log: convert tabs to spaces Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 14:12:56 2010 @@ -7,4 +7,4 @@ @cpython_api([PyObject], lltype.Float) def PyFloat_AsDouble(space, w_float): - return 10.0 #XXX: for now + return 10.0 #XXX: for now From xoraxax at codespeak.net Sat Mar 20 14:18:16 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 14:18:16 +0100 (CET) Subject: [pypy-svn] r72445 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100320131816.DDABE282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 14:18:15 2010 New Revision: 72445 Added: pypy/trunk/pypy/module/cpyext/test/__init__.py Removed: pypy/trunk/pypy/module/cpyext/test/autopath.py Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Log: Fix duplicate code, fix autopath imports. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 14:18:15 2010 @@ -1,7 +1,8 @@ -import py -import autopath import ctypes +import py + +from pypy.translator.goal import autopath from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.tool import rffi_platform from pypy.rpython.lltypesystem import ll2ctypes Added: pypy/trunk/pypy/module/cpyext/test/__init__.py ============================================================================== Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 14:18:15 2010 @@ -1,51 +1,9 @@ -from pypy.conftest import gettestobjspace -from pypy.interpreter.error import OperationError -from pypy.rpython.lltypesystem import rffi, lltype -from pypy.translator.tool.cbuild import ExternalCompilationInfo -from pypy.translator import platform -from pypy.module.cpyext import api -from test_cpyext import compile_module +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtension -import py, autopath +import py import sys -class AppTestFloatObject: - def setup_class(cls): - cls.api_library = api.build_bridge(cls.space, rename=True) - - def setup_method(self, func): - self.w_import_module = self.space.wrap(self.import_module) - - def teardown_method(self, func): - try: - self.space.delitem(self.space.sys.get('modules'), - self.space.wrap('foo')) - except OperationError: - pass - - def import_module(self, name, init, body=''): - code = """ - #include - #include - %(body)s - - void init%(name)s(void) { - %(init)s - } - """ % dict(name=name, init=init, body=body) - if sys.platform == 'win32': - libraries = [self.api_library] - mod = compile_module(name, code, libraries=libraries) - else: - libraries = [str(self.api_library+'.so')] - mod = compile_module(name, code, link_files=libraries) - import ctypes - initfunc = ctypes.CDLL(mod)['init%s' % (name,)] - initfunc() - return self.space.getitem( - self.space.sys.get('modules'), - self.space.wrap(name)) - +class AppTestFloatObject(AppTestCpythonExtension): def test_floatobject(self): import sys init = """ From xoraxax at codespeak.net Sat Mar 20 14:20:48 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 14:20:48 +0100 (CET) Subject: [pypy-svn] r72446 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100320132048.2C8BF282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 14:20:46 2010 New Revision: 72446 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Log: Oops, really fix autopath issue and only inherit from a clean base class. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 14:20:46 2010 @@ -1,12 +1,15 @@ +import sys + +import py + from pypy.conftest import gettestobjspace from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator import platform from pypy.module.cpyext import api +from pypy.translator.goal import autopath -import py, autopath -import sys class TestApi(): def test_signature(self): @@ -28,7 +31,7 @@ standalone=False) return str(soname) -class AppTestCpythonExtension: +class AppTestCpythonExtensionBase: def setup_class(cls): cls.api_library = api.build_bridge(cls.space, rename=True) @@ -65,6 +68,7 @@ except OperationError: pass +class AppTestCpythonExtension(AppTestCpythonExtensionBase): def test_createmodule(self): import sys init = """ Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 14:20:46 2010 @@ -1,9 +1,9 @@ -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtension +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase import py import sys -class AppTestFloatObject(AppTestCpythonExtension): +class AppTestFloatObject(AppTestCpythonExtensionBase): def test_floatobject(self): import sys init = """ From xoraxax at codespeak.net Sat Mar 20 14:35:00 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 14:35:00 +0100 (CET) Subject: [pypy-svn] r72447 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320133500.09B51282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 14:34:58 2010 New Revision: 72447 Modified: pypy/trunk/pypy/module/cpyext/api.py Log: Do not use zip here. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 14:34:58 2010 @@ -171,7 +171,8 @@ def wrapper(*args): boxed_args = [] # XXX use unrolling_iterable here - for typ, arg in zip(callable.api_func.argtypes, args): + for i, typ in enumerate(callable.api_func.argtypes): + arg = args[i] if typ is PyObject: arg = from_ref(space, arg) boxed_args.append(arg) From xoraxax at codespeak.net Sat Mar 20 14:35:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 14:35:21 +0100 (CET) Subject: [pypy-svn] r72448 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320133521.D516F282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 14:35:20 2010 New Revision: 72448 Modified: pypy/trunk/pypy/module/cpyext/methodobject.py Log: Issue an error message if from_ref fails here. Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sat Mar 20 14:35:20 2010 @@ -5,6 +5,8 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref +from pypy.rlib.objectmodel import we_are_translated + class W_PyCFunctionObject(Wrappable): def __init__(self, ml, w_self, w_modname): @@ -20,7 +22,15 @@ # Call the C function result = self.ml.c_ml_meth(null, null) - ret = from_ref(space, result) + try: + ret = from_ref(space, result) + except RuntimeError: + if not we_are_translated(): + import sys + print >>sys.stderr, "Calling a function failed. Did it" \ + " really return an PyObject?" + raise + # XXX result.decref() return ret From jandem at codespeak.net Sat Mar 20 14:55:57 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 14:55:57 +0100 (CET) Subject: [pypy-svn] r72449 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100320135557.8BB59282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 14:55:56 2010 New Revision: 72449 Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Log: fix the test Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 14:55:56 2010 @@ -15,10 +15,11 @@ { return PyFloat_FromDouble(3.14); } - double foo_AsDouble(PyObject* self, PyObject *args) + PyObject* foo_AsDouble(PyObject* self, PyObject *args) { PyObject* pi = PyFloat_FromDouble(3.14); - return PyFloat_AsDouble(pi); + double d = PyFloat_AsDouble(pi); + return PyFloat_FromDouble(d); } static PyMethodDef methods[] = { { "FromDouble", foo_FromDouble, METH_NOARGS }, From xoraxax at codespeak.net Sat Mar 20 15:07:41 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 15:07:41 +0100 (CET) Subject: [pypy-svn] r72450 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320140741.24617282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 15:07:39 2010 New Revision: 72450 Modified: pypy/trunk/pypy/module/cpyext/methodobject.py Log: Fix typo. Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sat Mar 20 15:07:39 2010 @@ -28,7 +28,7 @@ if not we_are_translated(): import sys print >>sys.stderr, "Calling a function failed. Did it" \ - " really return an PyObject?" + " really return a PyObject?" raise # XXX result.decref() From xoraxax at codespeak.net Sat Mar 20 15:08:01 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 15:08:01 +0100 (CET) Subject: [pypy-svn] r72451 - pypy/trunk/pypy/module/cpyext/include Message-ID: <20100320140801.0C399282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 15:07:59 2010 New Revision: 72451 Modified: pypy/trunk/pypy/module/cpyext/include/floatobject.h Log: Add forward decl (commented out). Modified: pypy/trunk/pypy/module/cpyext/include/floatobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/floatobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/floatobject.h Sat Mar 20 15:07:59 2010 @@ -9,6 +9,7 @@ PyObject* PyFloat_FromDouble(double); +//double PyFloat_AsDouble(PyObject*); #ifdef __cplusplus } From xoraxax at codespeak.net Sat Mar 20 15:08:25 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 15:08:25 +0100 (CET) Subject: [pypy-svn] r72452 - pypy/trunk/pypy/translator/platform Message-ID: <20100320140825.41862282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 15:08:23 2010 New Revision: 72452 Modified: pypy/trunk/pypy/translator/platform/__init__.py Log: Also show warnings when compiling. Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Sat Mar 20 15:08:23 2010 @@ -123,6 +123,9 @@ if len(stderrlines) > 50: log.ERROR('...') raise CompilationError(stdout, stderr) + else: + for line in stderr.splitlines(): + log.WARNING(line) def _compile_args_from_eci(self, eci, standalone): From xoraxax at codespeak.net Sat Mar 20 16:04:59 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 16:04:59 +0100 (CET) Subject: [pypy-svn] r72453 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320150459.AB4B5282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 16:04:58 2010 New Revision: 72453 Modified: pypy/trunk/pypy/module/cpyext/TODO Log: Add new TODO item. Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Sat Mar 20 16:04:58 2010 @@ -1,3 +1,3 @@ - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject - Add exceptions - + - Generate header files programmatically. From xoraxax at codespeak.net Sat Mar 20 16:05:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 16:05:13 +0100 (CET) Subject: [pypy-svn] r72454 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320150513.47B45282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 16:05:11 2010 New Revision: 72454 Modified: pypy/trunk/pypy/module/cpyext/macros.py Log: Add a single comment. Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sat Mar 20 16:05:11 2010 @@ -14,6 +14,7 @@ del state.py_objects_w2r[w_obj] ptr = ctypes.addressof(obj._obj._storage) del state.py_objects_r2w[ptr] + # XXX this will likely be somewhere else when we have grown a type object lltype.free(obj) else: assert obj.c_refcnt > 0 From xoraxax at codespeak.net Sat Mar 20 16:07:15 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 16:07:15 +0100 (CET) Subject: [pypy-svn] r72455 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320150715.F01DB282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 16:07:14 2010 New Revision: 72455 Added: pypy/trunk/pypy/module/cpyext/include/pyerrors.h pypy/trunk/pypy/module/cpyext/pyerrors.py Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/state.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Add exception handling to cpyext. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 16:07:14 2010 @@ -30,4 +30,5 @@ import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun import pypy.module.cpyext.macros +import pypy.module.cpyext.pyerrors api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 16:07:14 2010 @@ -12,6 +12,7 @@ from pypy.tool.udir import udir from pypy.translator import platform from pypy.module.cpyext.state import State +from pypy.interpreter.error import OperationError include_dirs = [ @@ -59,6 +60,12 @@ for name, TYPE in rffi_platform.configure(CConfig).iteritems(): TYPES[name].become(TYPE) +class NullPointerException(Exception): + pass + +class InvalidPointerException(Exception): + pass + def make_ref(space, w_obj): state = space.fromcache(State) py_obj = state.py_objects_w2r.get(w_obj) @@ -75,12 +82,12 @@ def from_ref(space, ref): state = space.fromcache(State) if not ref: - raise RuntimeError("Null pointer dereference!") + raise NullPointerException("Null pointer dereference!") ptr = ctypes.addressof(ref._obj._storage) try: obj = state.py_objects_r2w[ptr] except KeyError: - raise RuntimeError("Got invalid reference to a PyObject") + raise InvalidPointerException("Got invalid reference to a PyObject") return obj #_____________________________________________________ @@ -143,6 +150,7 @@ global_objects = """ PyObject *PyPy_None = NULL; + PyObject *PyPyExc_Exception = NULL; """ code = (prologue + struct_declaration_code + @@ -166,6 +174,7 @@ bridge = ctypes.CDLL(str(modulename)) pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') Py_NONE = ctypes.c_void_p.in_dll(bridge, 'PyPy_None') + PyExc_Exception = ctypes.c_void_p.in_dll(bridge, 'PyPyExc_Exception') def make_wrapper(callable): def wrapper(*args): @@ -176,7 +185,21 @@ if typ is PyObject: arg = from_ref(space, arg) boxed_args.append(arg) - retval = callable(space, *boxed_args) + try: + retval = callable(space, *boxed_args) + except OperationError, e: + e.normalize_exception(space) + state = space.fromcache(State) + state.exc_type = e.w_type + state.exc_value = e.get_w_value(space) + restype = callable.api_func.restype + if restype is lltype.Void: + return + if restype is PyObject: + return lltype.nullptr(PyObject) + if restype is lltype.Signed: + return -1 + assert False, "Unknown return type" if callable.api_func.restype is PyObject: retval = make_ref(space, retval) return retval @@ -189,6 +212,8 @@ ctypes.c_void_p) Py_NONE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_None)), ctypes.c_void_p).value + PyExc_Exception.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, + space.w_Exception)), ctypes.c_void_p).value return modulename.new(ext='') Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 16:07:14 2010 @@ -14,5 +14,6 @@ #include "modsupport.h" #include "pythonrun.h" +#include "pyerrors.h" #endif Added: pypy/trunk/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/pyerrors.h Sat Mar 20 16:07:14 2010 @@ -0,0 +1,16 @@ + +/* Exception interface */ + +#ifndef Py_PYERRORS_H +#define Py_PYERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +extern PyObject *PyPyExc_Exception; +#define PyExc_Exception PyPyExc_Exception + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYERRORS_H */ Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sat Mar 20 16:07:14 2010 @@ -3,8 +3,11 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import PyObject, from_ref +from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ + InvalidPointerException +from pypy.module.cpyext.state import State from pypy.rlib.objectmodel import we_are_translated @@ -24,11 +27,19 @@ result = self.ml.c_ml_meth(null, null) try: ret = from_ref(space, result) - except RuntimeError: + except NullPointerException: + state = space.fromcache(State) + exc_value = state.exc_value + exc_type = state.exc_type + assert exc_value is not None and exc_type is not None + state.exc_value = None + state.exc_type = None + raise OperationError(exc_type, exc_value) + except InvalidPointerException: if not we_are_translated(): import sys - print >>sys.stderr, "Calling a function failed. Did it" \ - " really return a PyObject?" + print >>sys.stderr, "Calling a C function return an invalid PyObject" \ + " pointer." raise # XXX result.decref() Added: pypy/trunk/pypy/module/cpyext/pyerrors.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/pyerrors.py Sat Mar 20 16:07:14 2010 @@ -0,0 +1,10 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.interpreter.error import OperationError +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref + + at cpython_api([PyObject, rffi.CCHARP], lltype.Void) +def PyErr_SetString(space, w_type, message_ptr): + message = rffi.charp2str(message_ptr) + w_obj = space.call_function(w_type, space.wrap(message)) + raise OperationError(w_type, w_obj) + Modified: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/state.py (original) +++ pypy/trunk/pypy/module/cpyext/state.py Sat Mar 20 16:07:14 2010 @@ -6,4 +6,6 @@ def __init__(self, space): self.py_objects_w2r = identity_dict() # w_obj -> raw PyObject self.py_objects_r2w = {} # addr of raw PyObject -> w_obj + self.exc_type = None + self.exc_value = None Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 16:07:14 2010 @@ -143,3 +143,29 @@ module.drop_pi() assert module.return_pi() == 3.14 assert module.return_pi() == 3.14 + + def test_exception(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + PyObject* foo_pi(PyObject* self, PyObject *args) + { + PyErr_SetString(PyExc_Exception, "moo!"); + return NULL; + } + static PyMethodDef methods[] = { + { "raise_exception", foo_pi, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + exc = raises(Exception, module.raise_exception) + if type(exc.value) is not Exception: + raise exc.value + + assert exc.value.message == "moo!" + + From xoraxax at codespeak.net Sat Mar 20 16:24:06 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 16:24:06 +0100 (CET) Subject: [pypy-svn] r72456 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100320152406.B1C73282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 16:24:05 2010 New Revision: 72456 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Add skipped tests that is useful to see how an rpython exception behaves. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 16:24:05 2010 @@ -11,6 +11,14 @@ from pypy.translator.goal import autopath + at api.cpython_api([], api.PyObject) +def PyPy_Crash1(space): + 1/0 + + at api.cpython_api([], lltype.Signed) +def PyPy_Crash2(space): + 1/0 + class TestApi(): def test_signature(self): assert 'Py_InitModule' in api.FUNCTIONS @@ -151,7 +159,7 @@ Py_InitModule("foo", methods); """ body = """ - PyObject* foo_pi(PyObject* self, PyObject *args) + static PyObject* foo_pi(PyObject* self, PyObject *args) { PyErr_SetString(PyExc_Exception, "moo!"); return NULL; @@ -168,4 +176,33 @@ assert exc.value.message == "moo!" + def test_internal_exceptions(self): + py.test.skip("Useful to see how programming errors look like") + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + static PyObject* foo_crash1(PyObject* self, PyObject *args) + { + return PyPy_Crash1(); + } + static PyObject* foo_crash2(PyObject* self, PyObject *args) + { + int a = PyPy_Crash2(); + if (a == -1) + return NULL; + return PyFloat_FromDouble(a); + } + static PyMethodDef methods[] = { + { "crash1", foo_crash1, METH_NOARGS }, + { "crash2", foo_crash2, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + module.crash1() + module.crash2() + From benjamin at codespeak.net Sat Mar 20 16:34:18 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sat, 20 Mar 2010 16:34:18 +0100 (CET) Subject: [pypy-svn] r72457 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320153418.D02EE282BD4@codespeak.net> Author: benjamin Date: Sat Mar 20 16:34:17 2010 New Revision: 72457 Modified: pypy/trunk/pypy/module/cpyext/include/pyerrors.h (props changed) pypy/trunk/pypy/module/cpyext/macros.py (props changed) pypy/trunk/pypy/module/cpyext/pyerrors.py (props changed) pypy/trunk/pypy/module/cpyext/state.py (props changed) pypy/trunk/pypy/module/cpyext/test/__init__.py (props changed) pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (props changed) Log: fix eol From arigo at codespeak.net Sat Mar 20 16:40:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 16:40:24 +0100 (CET) Subject: [pypy-svn] r72458 - pypy/branch/multijit/pypy/jit/metainterp/test Message-ID: <20100320154024.8F728282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 16:40:22 2010 New Revision: 72458 Modified: pypy/branch/multijit/pypy/jit/metainterp/test/test_basic.py Log: Fix. Modified: pypy/branch/multijit/pypy/jit/metainterp/test/test_basic.py ============================================================================== --- pypy/branch/multijit/pypy/jit/metainterp/test/test_basic.py (original) +++ pypy/branch/multijit/pypy/jit/metainterp/test/test_basic.py Sat Mar 20 16:40:22 2010 @@ -106,7 +106,7 @@ metainterp.staticdata.DoneWithThisFrameFloat = DoneWithThisFrame self.metainterp = metainterp try: - metainterp.compile_and_run_once(*args) + metainterp.compile_and_run_once(metainterp.staticdata, *args) except DoneWithThisFrame, e: #if conftest.option.view: # metainterp.stats.view() From jandem at codespeak.net Sat Mar 20 17:12:28 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 17:12:28 +0100 (CET) Subject: [pypy-svn] r72459 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320161228.72433282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 17:12:26 2010 New Revision: 72459 Added: pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h Log: add Py_True and Py_False, makes it easier to write tests Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 17:12:26 2010 @@ -150,6 +150,8 @@ global_objects = """ PyObject *PyPy_None = NULL; + PyObject *PyPy_True = NULL; + PyObject *PyPy_False = NULL; PyObject *PyPyExc_Exception = NULL; """ code = (prologue + @@ -174,6 +176,8 @@ bridge = ctypes.CDLL(str(modulename)) pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') Py_NONE = ctypes.c_void_p.in_dll(bridge, 'PyPy_None') + Py_TRUE = ctypes.c_void_p.in_dll(bridge, 'PyPy_True') + Py_FALSE = ctypes.c_void_p.in_dll(bridge, 'PyPy_False') PyExc_Exception = ctypes.c_void_p.in_dll(bridge, 'PyPyExc_Exception') def make_wrapper(callable): @@ -212,6 +216,10 @@ ctypes.c_void_p) Py_NONE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_None)), ctypes.c_void_p).value + Py_TRUE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_True)), + ctypes.c_void_p).value + Py_FALSE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_False)), + ctypes.c_void_p).value PyExc_Exception.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_Exception)), ctypes.c_void_p).value Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 17:12:26 2010 @@ -4,11 +4,13 @@ typedef struct _object { long refcnt; } PyObject; + extern PyObject *PyPy_None; #define Py_None PyPy_None #include +#include "boolobject.h" #include "floatobject.h" #include "methodobject.h" Added: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Sat Mar 20 17:12:26 2010 @@ -0,0 +1,20 @@ + +/* Bool object interface */ + +#ifndef Py_BOOLOBJECT_H +#define Py_BOOLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +extern PyObject *PyPy_True; +#define Py_True PyPy_True + +extern PyObject *PyPy_False; +#define Py_False PyPy_False + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ Added: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Sat Mar 20 17:12:26 2010 @@ -0,0 +1,33 @@ +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +import py +import sys + +class AppTestBoolObject(AppTestCpythonExtensionBase): + def test_boolobject(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + static PyObject* foo_GetTrue(PyObject* self, PyObject *args) + { + Py_INCREF(Py_True); + return Py_True; + } + static PyObject* foo_GetFalse(PyObject* self, PyObject *args) + { + Py_INCREF(Py_False); + return Py_False; + } + static PyMethodDef methods[] = { + { "GetTrue", foo_GetTrue, METH_NOARGS }, + { "GetFalse", foo_GetFalse, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert 'foo' in sys.modules + assert module.GetTrue() == True + assert module.GetFalse() == False From xoraxax at codespeak.net Sat Mar 20 18:01:31 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 18:01:31 +0100 (CET) Subject: [pypy-svn] r72460 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100320170131.895E8282BE4@codespeak.net> Author: xoraxax Date: Sat Mar 20 18:01:29 2010 New Revision: 72460 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Fix tests. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 18:01:29 2010 @@ -145,12 +145,13 @@ }; """ module = self.import_module(name='foo', init=init, body=body) - raises(RuntimeError, module.return_invalid_pointer) assert module.return_pi() == 3.14 module.drop_pi() module.drop_pi() assert module.return_pi() == 3.14 assert module.return_pi() == 3.14 + skip("Hmm, how to check for the exception?") + raises(api.InvalidPointerException, module.return_invalid_pointer) def test_exception(self): import sys @@ -177,7 +178,7 @@ assert exc.value.message == "moo!" def test_internal_exceptions(self): - py.test.skip("Useful to see how programming errors look like") + skip("Useful to see how programming errors look like") import sys init = """ if (Py_IsInitialized()) From jandem at codespeak.net Sat Mar 20 18:20:52 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 18:20:52 +0100 (CET) Subject: [pypy-svn] r72461 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320172052.51E62282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 18:20:50 2010 New Revision: 72461 Modified: pypy/trunk/pypy/module/cpyext/floatobject.py pypy/trunk/pypy/module/cpyext/include/floatobject.h pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Log: fix PyFloat_AsDouble Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 18:20:50 2010 @@ -6,5 +6,5 @@ return space.wrap(value) @cpython_api([PyObject], lltype.Float) -def PyFloat_AsDouble(space, w_float): - return 10.0 #XXX: for now +def PyFloat_AsDouble(space, w_obj): + return space.float_w(space.float(w_obj)) Modified: pypy/trunk/pypy/module/cpyext/include/floatobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/floatobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/floatobject.h Sat Mar 20 18:20:50 2010 @@ -7,9 +7,8 @@ extern "C" { #endif - PyObject* PyFloat_FromDouble(double); -//double PyFloat_AsDouble(PyObject*); +double PyFloat_AsDouble(PyObject*); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 18:20:50 2010 @@ -11,15 +11,15 @@ Py_InitModule("foo", methods); """ body = """ - PyObject* foo_FromDouble(PyObject* self, PyObject *args) + static PyObject* foo_FromDouble(PyObject* self, PyObject *args) { return PyFloat_FromDouble(3.14); } - PyObject* foo_AsDouble(PyObject* self, PyObject *args) + static PyObject* foo_AsDouble(PyObject* self, PyObject *args) { - PyObject* pi = PyFloat_FromDouble(3.14); - double d = PyFloat_AsDouble(pi); - return PyFloat_FromDouble(d); + PyObject* obj = PyFloat_FromDouble(23.45); + double d = PyFloat_AsDouble(obj); + return PyFloat_FromDouble(d); } static PyMethodDef methods[] = { { "FromDouble", foo_FromDouble, METH_NOARGS }, @@ -30,4 +30,4 @@ module = self.import_module(name='foo', init=init, body=body) assert 'foo' in sys.modules assert module.FromDouble() == 3.14 - assert module.AsDouble() == 3.14 + assert module.AsDouble() == 23.45 From jandem at codespeak.net Sat Mar 20 18:28:53 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 18:28:53 +0100 (CET) Subject: [pypy-svn] r72462 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100320172853.C1907282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 18:28:52 2010 New Revision: 72462 Modified: pypy/trunk/pypy/module/cpyext/macros.py pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Log: Fix Py_DECREF, lltype.free accepts two arguments Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sat Mar 20 18:28:52 2010 @@ -15,7 +15,7 @@ ptr = ctypes.addressof(obj._obj._storage) del state.py_objects_r2w[ptr] # XXX this will likely be somewhere else when we have grown a type object - lltype.free(obj) + lltype.free(obj, flavor='raw') else: assert obj.c_refcnt > 0 return Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Sat Mar 20 18:28:52 2010 @@ -19,6 +19,7 @@ { PyObject* obj = PyFloat_FromDouble(23.45); double d = PyFloat_AsDouble(obj); + Py_DECREF(obj); return PyFloat_FromDouble(d); } static PyMethodDef methods[] = { From xoraxax at codespeak.net Sat Mar 20 18:38:37 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 18:38:37 +0100 (CET) Subject: [pypy-svn] r72463 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100320173837.0D6B8282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 18:38:36 2010 New Revision: 72463 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/state.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Refactor test code, add new test that checks whether inits exception is respected, fix the bug. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 18:38:36 2010 @@ -225,3 +225,10 @@ return modulename.new(ext='') +def load_extension_module(space, path, name): + state = space.fromcache(State) + import ctypes + initfunc = ctypes.CDLL(path)['init%s' % (name,)] + initfunc() + state.check_and_raise_exception() + Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sat Mar 20 18:38:36 2010 @@ -3,7 +3,6 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ InvalidPointerException @@ -29,12 +28,8 @@ ret = from_ref(space, result) except NullPointerException: state = space.fromcache(State) - exc_value = state.exc_value - exc_type = state.exc_type - assert exc_value is not None and exc_type is not None - state.exc_value = None - state.exc_type = None - raise OperationError(exc_type, exc_value) + state.check_and_raise_exception() + assert False, "NULL returned but no exception set" except InvalidPointerException: if not we_are_translated(): import sys Modified: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/state.py (original) +++ pypy/trunk/pypy/module/cpyext/state.py Sat Mar 20 18:38:36 2010 @@ -1,6 +1,6 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.lib.identity_dict import identity_dict - +from pypy.interpreter.error import OperationError class State: def __init__(self, space): @@ -9,3 +9,11 @@ self.exc_type = None self.exc_value = None + def check_and_raise_exception(self): + exc_value = self.exc_value + exc_type = self.exc_type + if exc_type is not None or exc_value is not None: + self.exc_value = None + self.exc_type = None + raise OperationError(exc_type, exc_value) + Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sat Mar 20 18:38:36 2010 @@ -26,9 +26,8 @@ rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] assert api.FUNCTIONS['Py_InitModule'].restype == lltype.Void -def compile_module(modname, code, **kwds): +def compile_module(modname, **kwds): eci = ExternalCompilationInfo( - separate_module_sources=[code], export_symbols=['init%s' % (modname,)], include_dirs=api.include_dirs, **kwds @@ -43,25 +42,30 @@ def setup_class(cls): cls.api_library = api.build_bridge(cls.space, rename=True) - def import_module(self, name, init, body=''): - code = """ - #include - #include - %(body)s + def import_module(self, name, init=None, body=''): + if init is not None: + code = """ + #include + #include + %(body)s + + void init%(name)s(void) { + %(init)s + } + """ % dict(name=name, init=init, body=body) + kwds = dict(separate_module_sources=[code]) + else: + filename = py.path.local(autopath.pypydir) / 'module' \ + / 'cpyext'/ 'test' / (name + ".c") + kwds = dict(separate_module_files=[filename]) - void init%(name)s(void) { - %(init)s - } - """ % dict(name=name, init=init, body=body) if sys.platform == 'win32': - libraries = [self.api_library] - mod = compile_module(name, code, libraries=libraries) + kwds["libraries"] = [self.api_library] else: - libraries = [str(self.api_library+'.so')] - mod = compile_module(name, code, link_files=libraries) - import ctypes - initfunc = ctypes.CDLL(mod)['init%s' % (name,)] - initfunc() + kwds["link_files"] = [str(self.api_library + '.so')] + mod = compile_module(name, **kwds) + + api.load_extension_module(self.space, mod, name) return self.space.getitem( self.space.sys.get('modules'), self.space.wrap(name)) @@ -177,6 +181,18 @@ assert exc.value.message == "moo!" + def test_init_exception(self): + import sys + init = """ + PyErr_SetString(PyExc_Exception, "moo!"); + """ + exc = raises(Exception, "self.import_module(name='foo', init=init)") + if type(exc.value) is not Exception: + raise exc.value + + assert exc.value.message == "moo!" + + def test_internal_exceptions(self): skip("Useful to see how programming errors look like") import sys From arigo at codespeak.net Sat Mar 20 18:56:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 18:56:13 +0100 (CET) Subject: [pypy-svn] r72464 - in pypy/branch/rawffi-64/pypy/module/_rawffi: . test Message-ID: <20100320175613.A245F282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 18:56:11 2010 New Revision: 72464 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Log: Whack whack until one test passes. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 18:56:11 2010 @@ -12,8 +12,8 @@ from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import unwrap_value, wrap_value -from pypy.module._rawffi.interp_rawffi import letter2tp -from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment +from pypy.module._rawffi.interp_rawffi import TYPEMAP +from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length from pypy.rlib.rarithmetic import intmask, r_uint def push_elem(ll_array, pos, value): @@ -27,17 +27,30 @@ return ll_array[pos] get_elem._annspecialcase_ = 'specialize:arg(2)' + class W_Array(W_DataShape): - def __init__(self, space, itemtp): - assert isinstance(itemtp, tuple) - self.space = space - self.itemtp = itemtp + def __init__(self, basicffitype, multiplier=1, itemcode='?'): + # 'multiplier' is not the length of the array! + # A W_Array represent the C type '*T', which can also represent + # the type of pointers to arrays of T. So the following fields + # are used to describe T only. It is 'multiplier' times the + # 'basicffitype'. + self.basicffitype = basicffitype + self.multiplier = multiplier + # for the W_Arrays that represent simple types only: + self.itemcode = itemcode def allocate(self, space, length, autofree=False): if autofree: return W_ArrayInstanceAutoFree(space, self, length) return W_ArrayInstance(space, self, length) + def get_basic_ffi_type(self): + return self.basicffitype + + def get_ffi_type_with_length(self): + return self.basicffitype, self.multiplier + def descr_call(self, space, length, w_items=None, autofree=False): result = self.allocate(space, length, autofree) if not space.is_w(w_items, space.w_None): @@ -50,42 +63,34 @@ for num in range(iterlength): w_item = items_w[num] unwrap_value(space, push_elem, result.ll_buffer, num, - self.itemtp[0], w_item) + self.itemcode, w_item) return space.wrap(result) def descr_repr(self, space): - return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % self.itemtp) + return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % self.itemcode) descr_repr.unwrap_spec = ['self', ObjSpace] def fromaddress(self, space, address, length): return space.wrap(W_ArrayInstance(space, self, length, address)) fromaddress.unwrap_spec = ['self', ObjSpace, r_uint, int] - def _size_alignment(self): - _, itemsize, alignment = self.itemtp - return itemsize, alignment - -class ArrayCache: - def __init__(self, space): - self.space = space - self.cache = {} - self.array_of_ptr = self.get_array_type(letter2tp(space, 'P')) - - def get_array_type(self, itemtp): - try: - return self.cache[itemtp] - except KeyError: - result = W_Array(self.space, itemtp) - self.cache[itemtp] = result - return result - -def get_array_cache(space): - return space.fromcache(ArrayCache) +PRIMITIVE_ARRAY_TYPES = {} +for _code in TYPEMAP: + PRIMITIVE_ARRAY_TYPES[_code] = W_Array(TYPEMAP[_code], itemcode=_code) +ARRAY_OF_PTRS = PRIMITIVE_ARRAY_TYPES['P'] def descr_new_array(space, w_type, w_shape): - itemtp = unpack_to_size_alignment(space, w_shape) - array_type = get_array_cache(space).get_array_type(itemtp) - return space.wrap(array_type) + shape, length = unpack_shape_with_length(space, w_shape) + if length == 1: + return shape + if shape._array_shapes is None: + shape._array_shapes = {} + try: + result = shape._array_shapes[length] + except KeyError: + ffitype, lbase = shape.get_ffi_type_with_length() + result = shape._array_shapes[length] = W_Array(ffitype, lbase*length) + return result W_Array.typedef = TypeDef( 'Array', @@ -102,8 +107,7 @@ class W_ArrayInstance(W_DataInstance): def __init__(self, space, shape, length, address=r_uint(0)): - _, itemsize, _ = shape.itemtp - W_DataInstance.__init__(self, space, itemsize * length, address) + W_DataInstance.__init__(self, space, shape.size * length, address) self.length = length self.shape = shape @@ -122,7 +126,7 @@ if num >= self.length or num < 0: raise OperationError(space.w_IndexError, space.w_None) unwrap_value(space, push_elem, self.ll_buffer, num, - self.shape.itemtp[0], w_value) + self.shape.itemcode, w_value) def descr_setitem(self, space, w_index, w_value): try: @@ -141,7 +145,7 @@ if num >= self.length or num < 0: raise OperationError(space.w_IndexError, space.w_None) return wrap_value(space, get_elem, self.ll_buffer, num, - self.shape.itemtp) + self.shape.itemcode) def descr_getitem(self, space, w_index): try: Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Sat Mar 20 18:56:11 2010 @@ -52,9 +52,6 @@ def size_alignment(ffi_type): return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment) -UNPACKED_TYPECODES = dict([(code, (code,) + size_alignment(field_desc)) - for code, field_desc in TYPEMAP.items()]) - LL_TYPEMAP = { 'c' : rffi.CHAR, 'u' : lltype.UniChar, @@ -82,65 +79,41 @@ LL_TYPEMAP['v'] = rffi.SHORT def letter2tp(space, key): + from pypy.module._rawffi.array import PRIMITIVE_ARRAY_TYPES try: - return UNPACKED_TYPECODES[key] + return PRIMITIVE_ARRAY_TYPES[key] except KeyError: raise operationerrfmt(space.w_ValueError, "Unknown type letter %s", key) -def _get_type_(space, key): - try: - return TYPEMAP[key] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "Unknown type letter %s", key) - -def unpack_to_ffi_type(space, w_shape, shape=False): - resshape = None +def unpack_simple_shape(space, w_shape): + # 'w_shape' must be either a letter or a tuple (struct, 1). if space.is_true(space.isinstance(w_shape, space.w_str)): letter = space.str_w(w_shape) - ffi_type = _get_type_(space, letter) - if shape: - from pypy.module._rawffi.array import get_array_cache - cache = get_array_cache(space) - resshape = cache.get_array_type(letter2tp(space, letter)) + return letter2tp(space, letter) else: - letter = 'V' w_shapetype, w_length = space.fixedview(w_shape, expected_length=2) from pypy.module._rawffi.structure import W_Structure - resshape = space.interp_w(W_Structure, w_shapetype) - ffi_type = resshape.get_ffi_type() - return letter, ffi_type, resshape + return space.interp_w(W_Structure, w_shapetype) -def unpack_to_size_alignment(space, w_shape): +def unpack_shape_with_length(space, w_shape): + # allow 'w_shape' to be a letter or any (shape, number). if space.is_true(space.isinstance(w_shape, space.w_str)): letter = space.str_w(w_shape) - return letter2tp(space, letter) + return letter2tp(space, letter), 1 else: w_shapetype, w_length = space.fixedview(w_shape, expected_length=2) - resshape = space.interp_w(W_DataShape, w_shapetype) length = space.int_w(w_length) - size, alignment = resshape._size_alignment() - return ('V', length*size, alignment) # value object + return space.interp_w(W_DataShape, w_shapetype), length def unpack_resshape(space, w_restype): if space.is_w(w_restype, space.w_None): - resshape = None - ffi_restype = ffi_type_void - else: - tp_letter, ffi_restype, resshape = unpack_to_ffi_type(space, - w_restype, - shape=True) - return ffi_restype, resshape + return None + return unpack_simple_shape(space, w_restype) def unpack_argshapes(space, w_argtypes): - argletters = [] - ffi_argtypes = [] - for w_arg in space.unpackiterable(w_argtypes): - argletter, ffi_argtype, _ = unpack_to_ffi_type(space, w_arg) - argletters.append(argletter) - ffi_argtypes.append(ffi_argtype) - return ffi_argtypes, argletters + return [unpack_simple_shape(space, w_arg) + for w_arg in space.unpackiterable(w_argtypes)] class W_CDLL(Wrappable): def __init__(self, space, name): @@ -157,7 +130,7 @@ """ Get a pointer for function name with provided argtypes and restype """ - ffi_restype, resshape = unpack_resshape(space, w_restype) + resshape = unpack_resshape(space, w_restype) w = space.wrap argtypes_w = space.fixedview(w_argtypes) w_argtypes = space.newtuple(argtypes_w) @@ -169,7 +142,12 @@ pass else: raise - ffi_argtypes, argletters = unpack_argshapes(space, w_argtypes) + argshapes = unpack_argshapes(space, w_argtypes) + ffi_argtypes = [shape.get_basic_ffi_type() for shape in argshapes] + if resshape is not None: + ffi_restype = resshape.get_basic_ffi_type() + else: + ffi_restype = ffi_type_void if space.is_true(space.isinstance(w_name, space.w_str)): name = space.str_w(w_name) @@ -194,7 +172,7 @@ raise OperationError(space.w_TypeError, space.wrap( "function name must be string or integer")) - w_funcptr = W_FuncPtr(space, ptr, argletters, resshape) + w_funcptr = W_FuncPtr(space, ptr, argshapes, resshape) space.setitem(self.w_cache, w_key, w_funcptr) return w_funcptr ptr.unwrap_spec = ['self', ObjSpace, W_Root, W_Root, W_Root, int] @@ -240,17 +218,22 @@ return OperationError(w_exception, space.wrap(reason)) class W_DataShape(Wrappable): + _array_shapes = None + size = 0 + alignment = 0 def allocate(self, space, length, autofree=False): raise NotImplementedError - def _size_alignment(self): + def get_basic_ffi_type(self): raise NotImplementedError - + + def get_ffi_type_with_length(self): + return self.get_basic_ffi_type(), 1 # default implementation + def descr_size_alignment(self, space, n=1): - size, alignment = self._size_alignment() - return space.newtuple([space.wrap(size * n), - space.wrap(alignment)]) + return space.newtuple([space.wrap(self.size * n), + space.wrap(self.alignment)]) descr_size_alignment.unwrap_spec = ['self', ObjSpace, int] @@ -269,9 +252,8 @@ return space.wrap(rffi.cast(lltype.Unsigned, self.ll_buffer)) def byptr(self, space): - from pypy.module._rawffi.array import get_array_cache - array_of_ptr = get_array_cache(space).array_of_ptr - array = array_of_ptr.allocate(space, 1) + from pypy.module._rawffi.array import ARRAY_OF_PTRS + array = ARRAY_OF_PTRS.allocate(space, 1) array.setitem(space, 0, space.wrap(self)) return space.wrap(array) byptr.unwrap_spec = ['self', ObjSpace] @@ -306,12 +288,7 @@ def unwrap_value(space, push_func, add_arg, argdesc, letter, w_arg): w = space.wrap - if letter == "d": - push_func(add_arg, argdesc, space.float_w(w_arg)) - elif letter == "f": - push_func(add_arg, argdesc, rffi.cast(rffi.FLOAT, - space.float_w(w_arg))) - elif letter in TYPEMAP_PTR_LETTERS: + if letter in TYPEMAP_PTR_LETTERS: # check for NULL ptr datainstance = space.interpclass_w(w_arg) if isinstance(datainstance, W_DataInstance): @@ -319,6 +296,11 @@ else: ptr = unwrap_truncate_int(rffi.VOIDP, space, w_arg) push_func(add_arg, argdesc, ptr) + elif letter == "d": + push_func(add_arg, argdesc, space.float_w(w_arg)) + elif letter == "f": + push_func(add_arg, argdesc, rffi.cast(rffi.FLOAT, + space.float_w(w_arg))) elif letter == "c": s = space.str_w(w_arg) if len(s) != 1: @@ -347,8 +329,7 @@ ll_typemap_iter = unrolling_iterable(LL_TYPEMAP.items()) -def wrap_value(space, func, add_arg, argdesc, tp): - letter, _, _ = tp +def wrap_value(space, func, add_arg, argdesc, letter): for c, ll_type in ll_typemap_iter: if letter == c: if c in TYPEMAP_PTR_LETTERS: @@ -365,9 +346,9 @@ wrap_value._annspecialcase_ = 'specialize:arg(1)' class W_FuncPtr(Wrappable): - def __init__(self, space, ptr, argletters, resshape): + def __init__(self, space, ptr, argshapes, resshape): self.ptr = ptr - self.argletters = argletters + self.argshapes = argshapes self.resshape = resshape def getbuffer(space, self): @@ -393,16 +374,17 @@ def call(self, space, args_w): from pypy.module._rawffi.array import W_ArrayInstance from pypy.module._rawffi.structure import W_StructureInstance + from pypy.module._rawffi.structure import W_Structure argnum = len(args_w) - if argnum != len(self.argletters): + if argnum != len(self.argshapes): msg = "Wrong number of arguments: expected %d, got %d" raise operationerrfmt(space.w_TypeError, msg, - len(self.argletters), argnum) + len(self.argshapes), argnum) args_ll = [] for i in range(argnum): - argletter = self.argletters[i] + argshape = self.argshapes[i] w_arg = args_w[i] - if argletter == 'V': # by value object + if isinstance(argshape, W_Structure): # argument by value arg = space.interp_w(W_StructureInstance, w_arg) xsize, xalignment = size_alignment(self.ptr.argtypes[i]) if (arg.shape.size != xsize or @@ -420,7 +402,8 @@ "got length %d") raise operationerrfmt(space.w_TypeError, msg, i+1, arg.length) - letter = arg.shape.itemtp[0] + argletter = argshape.itemcode + letter = arg.shape.itemcode if letter != argletter: if not (argletter in TYPEMAP_PTR_LETTERS and letter in TYPEMAP_PTR_LETTERS): Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Sat Mar 20 18:56:11 2010 @@ -13,7 +13,7 @@ from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value -from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment +#from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment from pypy.rlib import libffi from pypy.rlib.rarithmetic import intmask, r_uint @@ -99,13 +99,10 @@ return space.wrap(self.ll_positions[index]) descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str] - def _size_alignment(self): - return self.size, self.alignment - # get the corresponding ffi_type ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO) - def get_ffi_type(self): + def get_basic_ffi_type(self): if not self.ffi_type: self.ffi_type = libffi.make_struct_ffitype(self.size, self.alignment) Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Sat Mar 20 18:56:11 2010 @@ -141,6 +141,16 @@ return inp; } + struct s2a { + int bah[2]; + }; + + struct s2a perturbarray(struct s2a inp) { + inp.bah[0] *= 4; + inp.bah[1] *= 5; + return inp; + } + int AAA_first_ordinal_function() { return 42; @@ -157,7 +167,7 @@ allocate_array static_int static_double sum_x_y - give perturb + give perturb perturbarray AAA_first_ordinal_function """.split() eci = ExternalCompilationInfo(export_symbols=symbols) @@ -819,19 +829,22 @@ assert 0, "Did not raise" def test_struct_byvalue(self): - if self.isx86_64: - skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") + #if self.isx86_64: + # skip("Segfaults on x86_64 because small structures " + # "may be passed in registers and " + # "c_elements must not be null") - import _rawffi + import _rawffi, sys X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')]) x_y = X_Y() lib = _rawffi.CDLL(self.lib_name) + print >> sys.stderr, "getting..." sum_x_y = lib.ptr('sum_x_y', [(X_Y, 1)], 'l') x_y.x = 200 x_y.y = 220 + print >> sys.stderr, "calling..." res = sum_x_y(x_y) + print >> sys.stderr, "done" assert res[0] == 420 x_y.free() @@ -871,6 +884,41 @@ s2h.free() + def test_ret_struct_containing_array(self): + if self.isx86_64: + skip("Segfaults on x86_64 because small structures " + "may be passed in registers and " + "c_elements must not be null") + + import _rawffi + AoI = _rawffi.Array('i') + S2A = _rawffi.Structure([('bah', (AoI, 2))]) + s2a = S2A() + lib = _rawffi.CDLL(self.lib_name) + perturbarray = lib.ptr('perturbarray', [(S2A, 1)], (S2A, 1)) + s2a.x = 100 + a2a.y = 200 + res = perturbarray(s2a) + assert isinstance(res, _rawffi.StructureInstanceAutoFree) + assert res.shape is S2H + assert res.x == 13 + assert res.y == 17 + a1.free() + a2.free() + + s2h.x = 7 + s2h.y = 11 + perturb = lib.ptr('perturb', [(S2H, 1)], (S2H, 1)) + res = perturb(s2h) + assert isinstance(res, _rawffi.StructureInstanceAutoFree) + assert res.shape is S2H + assert res.x == 14 + assert res.y == 33 + assert s2h.x == 7 + assert s2h.y == 11 + + s2h.free() + def test_buffer(self): import _rawffi S = _rawffi.Structure((40, 1)) From arigo at codespeak.net Sat Mar 20 19:10:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 19:10:36 +0100 (CET) Subject: [pypy-svn] r72465 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320181036.A6400282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 19:10:35 2010 New Revision: 72465 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Log: A bit of progress. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 19:10:35 2010 @@ -13,6 +13,7 @@ from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import unwrap_value, wrap_value from pypy.module._rawffi.interp_rawffi import TYPEMAP +from pypy.module._rawffi.interp_rawffi import size_alignment from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length from pypy.rlib.rarithmetic import intmask, r_uint @@ -29,14 +30,15 @@ class W_Array(W_DataShape): - def __init__(self, basicffitype, multiplier=1, itemcode='?'): - # 'multiplier' is not the length of the array! + def __init__(self, basicffitype, size, itemcode='?'): # A W_Array represent the C type '*T', which can also represent # the type of pointers to arrays of T. So the following fields - # are used to describe T only. It is 'multiplier' times the - # 'basicffitype'. + # are used to describe T only. It is 'basicffitype' possibly + # repeated until reaching the length 'size'. + assert size > 0 self.basicffitype = basicffitype - self.multiplier = multiplier + self.size = size + self.alignment = size_alignment(basicffitype)[1] # for the W_Arrays that represent simple types only: self.itemcode = itemcode @@ -45,12 +47,9 @@ return W_ArrayInstanceAutoFree(space, self, length) return W_ArrayInstance(space, self, length) - def get_basic_ffi_type(self): + def get_ffi_type(self): return self.basicffitype - def get_ffi_type_with_length(self): - return self.basicffitype, self.multiplier - def descr_call(self, space, length, w_items=None, autofree=False): result = self.allocate(space, length, autofree) if not space.is_w(w_items, space.w_None): @@ -76,7 +75,9 @@ PRIMITIVE_ARRAY_TYPES = {} for _code in TYPEMAP: - PRIMITIVE_ARRAY_TYPES[_code] = W_Array(TYPEMAP[_code], itemcode=_code) + PRIMITIVE_ARRAY_TYPES[_code] = W_Array(TYPEMAP[_code], + size_alignment(TYPEMAP[_code])[0], + _code) ARRAY_OF_PTRS = PRIMITIVE_ARRAY_TYPES['P'] def descr_new_array(space, w_type, w_shape): @@ -88,8 +89,9 @@ try: result = shape._array_shapes[length] except KeyError: - ffitype, lbase = shape.get_ffi_type_with_length() - result = shape._array_shapes[length] = W_Array(ffitype, lbase*length) + ffitype = shape.get_ffi_type() + size = shape.size * length + result = shape._array_shapes[length] = W_Array(ffitype, size) return result W_Array.typedef = TypeDef( @@ -176,7 +178,7 @@ if not space.is_true(space.isinstance(w_slice, space.w_slice)): raise OperationError(space.w_TypeError, space.wrap('index must be int or slice')) - letter, _, _ = self.shape.itemtp + letter = self.shape.itemcode if letter != 'c': raise OperationError(space.w_TypeError, space.wrap("only 'c' arrays support slicing")) Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Sat Mar 20 19:10:35 2010 @@ -143,9 +143,9 @@ else: raise argshapes = unpack_argshapes(space, w_argtypes) - ffi_argtypes = [shape.get_basic_ffi_type() for shape in argshapes] + ffi_argtypes = [shape.get_ffi_type() for shape in argshapes] if resshape is not None: - ffi_restype = resshape.get_basic_ffi_type() + ffi_restype = resshape.get_ffi_type() else: ffi_restype = ffi_type_void @@ -221,16 +221,13 @@ _array_shapes = None size = 0 alignment = 0 - + def allocate(self, space, length, autofree=False): raise NotImplementedError - def get_basic_ffi_type(self): + def get_ffi_type(self): raise NotImplementedError - def get_ffi_type_with_length(self): - return self.get_basic_ffi_type(), 1 # default implementation - def descr_size_alignment(self, space, n=1): return space.newtuple([space.wrap(self.size * n), space.wrap(self.alignment)]) Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Sat Mar 20 19:10:35 2010 @@ -100,9 +100,7 @@ descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str] # get the corresponding ffi_type - ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO) - - def get_basic_ffi_type(self): + def get_ffi_type(self): if not self.ffi_type: self.ffi_type = libffi.make_struct_ffitype(self.size, self.alignment) From arigo at codespeak.net Sat Mar 20 19:14:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 19:14:18 +0100 (CET) Subject: [pypy-svn] r72466 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320181418.A8CA1282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 19:14:17 2010 New Revision: 72466 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Log: More passing tests. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Sat Mar 20 19:14:17 2010 @@ -357,9 +357,8 @@ return space.wrap(rffi.cast(lltype.Unsigned, self.ptr.funcsym)) def byptr(self, space): - from pypy.module._rawffi.array import get_array_cache - array_of_ptr = get_array_cache(space).array_of_ptr - array = array_of_ptr.allocate(space, 1) + from pypy.module._rawffi.array import ARRAY_OF_PTRS + array = ARRAY_OF_PTRS.allocate(space, 1) array.setitem(space, 0, self._getbuffer(space)) if tracker.DO_TRACING: # XXX this is needed, because functions tend to live forever @@ -423,11 +422,13 @@ call.unwrap_spec = ['self', ObjSpace, 'args_w'] def descr_new_funcptr(space, w_tp, addr, w_args, w_res, flags=FUNCFLAG_CDECL): - ffi_args, args = unpack_argshapes(space, w_args) - ffi_res, res = unpack_resshape(space, w_res) + argshapes = unpack_argshapes(space, w_args) + resshape = unpack_resshape(space, w_res) + ffi_args = [shape.get_ffi_type() for shape in argshapes] + ffi_res = resshape.get_ffi_type() ptr = RawFuncPtr('???', ffi_args, ffi_res, rffi.cast(rffi.VOIDP, addr), flags) - return space.wrap(W_FuncPtr(space, ptr, args, res)) + return space.wrap(W_FuncPtr(space, ptr, argshapes, resshape)) descr_new_funcptr.unwrap_spec = [ObjSpace, W_Root, r_uint, W_Root, W_Root, int] W_FuncPtr.typedef = TypeDef( From arigo at codespeak.net Sat Mar 20 19:25:49 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 19:25:49 +0100 (CET) Subject: [pypy-svn] r72467 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320182549.E695B282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 19:25:48 2010 New Revision: 72467 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Log: Pass more tests. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 19:25:48 2010 @@ -30,7 +30,7 @@ class W_Array(W_DataShape): - def __init__(self, basicffitype, size, itemcode='?'): + def __init__(self, basicffitype, size): # A W_Array represent the C type '*T', which can also represent # the type of pointers to arrays of T. So the following fields # are used to describe T only. It is 'basicffitype' possibly @@ -39,8 +39,6 @@ self.basicffitype = basicffitype self.size = size self.alignment = size_alignment(basicffitype)[1] - # for the W_Arrays that represent simple types only: - self.itemcode = itemcode def allocate(self, space, length, autofree=False): if autofree: @@ -76,23 +74,12 @@ PRIMITIVE_ARRAY_TYPES = {} for _code in TYPEMAP: PRIMITIVE_ARRAY_TYPES[_code] = W_Array(TYPEMAP[_code], - size_alignment(TYPEMAP[_code])[0], - _code) + size_alignment(TYPEMAP[_code])[0]) + PRIMITIVE_ARRAY_TYPES[_code].itemcode = _code ARRAY_OF_PTRS = PRIMITIVE_ARRAY_TYPES['P'] def descr_new_array(space, w_type, w_shape): - shape, length = unpack_shape_with_length(space, w_shape) - if length == 1: - return shape - if shape._array_shapes is None: - shape._array_shapes = {} - try: - result = shape._array_shapes[length] - except KeyError: - ffitype = shape.get_ffi_type() - size = shape.size * length - result = shape._array_shapes[length] = W_Array(ffitype, size) - return result + return unpack_shape_with_length(space, w_shape) W_Array.typedef = TypeDef( 'Array', Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Sat Mar 20 19:25:48 2010 @@ -97,14 +97,29 @@ return space.interp_w(W_Structure, w_shapetype) def unpack_shape_with_length(space, w_shape): - # allow 'w_shape' to be a letter or any (shape, number). + # Allow 'w_shape' to be a letter or any (shape, number). + # The result is always a W_Array. if space.is_true(space.isinstance(w_shape, space.w_str)): letter = space.str_w(w_shape) - return letter2tp(space, letter), 1 + return letter2tp(space, letter) else: w_shapetype, w_length = space.fixedview(w_shape, expected_length=2) length = space.int_w(w_length) - return space.interp_w(W_DataShape, w_shapetype), length + shape = space.interp_w(W_DataShape, w_shapetype) + if shape._array_shapes is None: + shape._array_shapes = {} + try: + result = shape._array_shapes[length] + except KeyError: + from pypy.module._rawffi.array import W_Array + if isinstance(shape, W_Array) and length == 1: + result = shape + else: + ffitype = shape.get_ffi_type() + size = shape.size * length + result = W_Array(ffitype, size) + shape._array_shapes[length] = result + return result def unpack_resshape(space, w_restype): if space.is_w(w_restype, space.w_None): @@ -221,6 +236,7 @@ _array_shapes = None size = 0 alignment = 0 + itemcode = '?' def allocate(self, space, length, autofree=False): raise NotImplementedError Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Sat Mar 20 19:25:48 2010 @@ -13,7 +13,7 @@ from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value -#from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment +from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length from pypy.rlib import libffi from pypy.rlib.rarithmetic import intmask, r_uint @@ -26,7 +26,7 @@ raise OperationError(space.w_ValueError, space.wrap( "Expected list of 2-size tuples")) name = space.str_w(l_w[0]) - tp = unpack_to_size_alignment(space, l_w[1]) + tp = unpack_shape_with_length(space, l_w[1]) fields.append((name, tp)) return fields @@ -37,7 +37,10 @@ size = 0 alignment = 1 pos = [] - for fieldname, (letter, fieldsize, fieldalignment) in fields: + for fieldname, fieldtype in fields: + # fieldtype is a W_Array + fieldsize = fieldtype.size + fieldalignment = fieldtype.alignment size = round_up(size, fieldalignment) alignment = max(alignment, fieldalignment) pos.append(size) @@ -163,7 +166,7 @@ raise segfault_exception(space, "accessing NULL pointer") i = self.shape.getindex(space, attr) _, tp = self.shape.fields[i] - return wrap_value(space, cast_pos, self, i, tp) + return wrap_value(space, cast_pos, self, i, tp.itemcode) getattr.unwrap_spec = ['self', ObjSpace, str] def setattr(self, space, attr, w_value): @@ -171,7 +174,7 @@ raise segfault_exception(space, "accessing NULL pointer") i = self.shape.getindex(space, attr) _, tp = self.shape.fields[i] - unwrap_value(space, push_field, self, i, tp[0], w_value) + unwrap_value(space, push_field, self, i, tp.itemcode, w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] def descr_fieldaddress(self, space, attr): From jandem at codespeak.net Sat Mar 20 19:35:06 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 19:35:06 +0100 (CET) Subject: [pypy-svn] r72468 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320183506.4025F282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 19:35:04 2010 New Revision: 72468 Modified: pypy/trunk/pypy/module/cpyext/floatobject.py pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Log: Add Py_RETURN_{TRUE,FALSE} macros and fix style Modified: pypy/trunk/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/floatobject.py Sat Mar 20 19:35:04 2010 @@ -1,5 +1,5 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.api import cpython_api, PyObject @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): Modified: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Sat Mar 20 19:35:04 2010 @@ -7,13 +7,16 @@ extern "C" { #endif - extern PyObject *PyPy_True; #define Py_True PyPy_True extern PyObject *PyPy_False; #define Py_False PyPy_False +/* Macros for returning Py_True or Py_False, respectively */ +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False + #ifdef __cplusplus } #endif Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Sat Mar 20 19:35:04 2010 @@ -11,23 +11,21 @@ Py_InitModule("foo", methods); """ body = """ - static PyObject* foo_GetTrue(PyObject* self, PyObject *args) + static PyObject* foo_get_true(PyObject* self, PyObject *args) { - Py_INCREF(Py_True); - return Py_True; + Py_RETURN_TRUE; } - static PyObject* foo_GetFalse(PyObject* self, PyObject *args) + static PyObject* foo_get_false(PyObject* self, PyObject *args) { - Py_INCREF(Py_False); - return Py_False; + Py_RETURN_FALSE; } static PyMethodDef methods[] = { - { "GetTrue", foo_GetTrue, METH_NOARGS }, - { "GetFalse", foo_GetFalse, METH_NOARGS }, + { "get_true", foo_get_true, METH_NOARGS }, + { "get_false", foo_get_false, METH_NOARGS }, { NULL } }; """ module = self.import_module(name='foo', init=init, body=body) assert 'foo' in sys.modules - assert module.GetTrue() == True - assert module.GetFalse() == False + assert module.get_true() == True + assert module.get_false() == False From arigo at codespeak.net Sat Mar 20 19:39:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 19:39:29 +0100 (CET) Subject: [pypy-svn] r72469 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320183929.4A9C5282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 19:39:27 2010 New Revision: 72469 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Log: Start to pass the tests about callback. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py Sat Mar 20 19:39:27 2010 @@ -6,8 +6,9 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.module._rawffi.structure import unpack_fields from pypy.module._rawffi.array import get_elem, push_elem -from pypy.module._rawffi.interp_rawffi import W_DataInstance, _get_type_,\ - wrap_value, unwrap_value, unwrap_truncate_int, letter2tp +from pypy.module._rawffi.interp_rawffi import W_DataInstance, \ + wrap_value, unwrap_value, unwrap_truncate_int, \ + unpack_argshapes, unpack_resshape from pypy.rlib.libffi import USERDATA_P, CallbackFuncPtr, FUNCFLAG_CDECL from pypy.module._rawffi.tracker import tracker from pypy.interpreter.error import OperationError @@ -26,21 +27,23 @@ userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable - argtypes = callback_ptr.args + argshapes = callback_ptr.argshapes space = callback_ptr.space try: + # XXX The app-level callback gets the arguments as a list of integers. + # Irregular interface here. Shows something, I say. w_args = space.newlist([space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) - for i in range(len(argtypes))]) + for i in range(len(argshapes))]) w_res = space.call(w_callable, w_args) - if callback_ptr.result != 'O': # don't return void + if callback_ptr.resshape is not None: # don't return void unwrap_value(space, push_elem, ll_res, 0, - callback_ptr.result, w_res) + callback_ptr.resshape.itemcode, w_res) except OperationError, e: tbprint(space, space.wrap(e.application_traceback), space.wrap(e.errorstr(space))) # force the result to be zero - if callback_ptr.result != 'O': - _, size, _ = letter2tp(space, callback_ptr.result) + if callback_ptr.resshape is not None: + size = callback_ptr.resshape.size for i in range(size): ll_res[i] = '\x00' @@ -58,18 +61,20 @@ def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): + self.space = space + self.w_callable = w_callable + self.argshapes = unpack_argshapes(space, w_args) + self.resshape = unpack_resshape(space, w_result) + ffiargs = [shape.get_ffi_type() for shape in self.argshapes] + if self.resshape is not None: + ffiresult = self.resshape.get_ffi_type() + else: + ffiresult = ffi_type_void + # necessary to keep stuff alive number = global_counter.CallbackPtr_id global_counter.CallbackPtr_id += 1 global_counter.CallbackPtr_by_number[number] = self - self.space = space - self.w_callable = w_callable self.number = number - self.args = [space.str_w(w_arg) for w_arg in space.unpackiterable( - w_args)] - self.result = space.str_w(w_result) - ffiargs = [_get_type_(space, arg) for arg in self.args] - ffiresult = _get_type_(space, self.result) - # necessary to keep stuff alive self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, number, flags) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.ll_closure) Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Sat Mar 20 19:39:27 2010 @@ -103,6 +103,8 @@ descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str] # get the corresponding ffi_type + ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO) + def get_ffi_type(self): if not self.ffi_type: self.ffi_type = libffi.make_struct_ffitype(self.size, From xoraxax at codespeak.net Sat Mar 20 19:42:37 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 19:42:37 +0100 (CET) Subject: [pypy-svn] r72470 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320184237.77DCD282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 19:42:35 2010 New Revision: 72470 Added: pypy/trunk/pypy/module/cpyext/include/descrobject.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/stringobject.h pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/stringobject.py pypy/trunk/pypy/module/cpyext/test/foo.c pypy/trunk/pypy/module/cpyext/test/test_typeobject.py pypy/trunk/pypy/module/cpyext/typeobject.py Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h Log: Intermediary checkin, added foo.c which is a simple module with a type object, added pytypeobject and dependencies to the header files. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 19:42:35 2010 @@ -31,4 +31,6 @@ import pypy.module.cpyext.pythonrun import pypy.module.cpyext.macros import pypy.module.cpyext.pyerrors +import pypy.module.cpyext.typeobject +import pypy.module.cpyext.object api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 19:42:35 2010 @@ -14,6 +14,7 @@ from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError +Py_ssize_t = lltype.Signed include_dirs = [ py.path.local(autopath.pypydir).join('module', 'cpyext', 'include'), Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 19:42:35 2010 @@ -1,9 +1,12 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H -typedef struct _object { - long refcnt; -} PyObject; +#include +#include +typedef long Py_ssize_t; +#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) + +#include "object.h" extern PyObject *PyPy_None; #define Py_None PyPy_None @@ -17,5 +20,7 @@ #include "modsupport.h" #include "pythonrun.h" #include "pyerrors.h" +#include "stringobject.h" +#include "descrobject.h" #endif Added: pypy/trunk/pypy/module/cpyext/include/descrobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/descrobject.h Sat Mar 20 19:42:35 2010 @@ -0,0 +1,15 @@ +#ifndef Py_DESCROBJECT_H +#define Py_DESCROBJECT_H +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + char *name; + getter get; + setter set; + char *doc; + void *closure; +} PyGetSetDef; + + +#endif Added: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sat Mar 20 19:42:35 2010 @@ -0,0 +1,381 @@ +#ifndef Py_OBJECT_H +#define Py_OBJECT_H + +#include + +typedef struct _object { + long refcnt; +} PyObject; + +typedef void* Py_buffer; + +#define PyObject_HEAD \ + long refcnt; + +#define PyObject_VAR_HEAD \ + PyObject_HEAD \ + Py_ssize_t ob_size; /* Number of items in variable part */ + +#define PyObject_HEAD_INIT(type) \ + 1, /* XXX type, */ + +#define PyVarObject_HEAD_INIT(type, size) \ + PyObject_HEAD_INIT(type) size, + + +extern PyObject *PyPy_None; +#define Py_None PyPy_None + +struct _typeobject; +typedef void (*freefunc)(void *); +typedef void (*destructor)(PyObject *); +typedef int (*printfunc)(PyObject *, FILE *, int); +typedef PyObject *(*getattrfunc)(PyObject *, char *); +typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); +typedef int (*setattrfunc)(PyObject *, char *, PyObject *); +typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); +typedef int (*cmpfunc)(PyObject *, PyObject *); +typedef PyObject *(*reprfunc)(PyObject *); +typedef long (*hashfunc)(PyObject *); +typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); +typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); +typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*initproc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); + +typedef PyObject * (*unaryfunc)(PyObject *); +typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); +typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); +typedef int (*inquiry)(PyObject *); +typedef Py_ssize_t (*lenfunc)(PyObject *); +typedef int (*coercion)(PyObject **, PyObject **); +typedef PyObject *(*intargfunc)(PyObject *, int) Py_DEPRECATED(2.5); +typedef PyObject *(*intintargfunc)(PyObject *, int, int) Py_DEPRECATED(2.5); +typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); +typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); +typedef int(*intobjargproc)(PyObject *, int, PyObject *); +typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *); +typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); +typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); + + +/* int-based buffer interface */ +typedef int (*getreadbufferproc)(PyObject *, int, void **); +typedef int (*getwritebufferproc)(PyObject *, int, void **); +typedef int (*getsegcountproc)(PyObject *, int *); +typedef int (*getcharbufferproc)(PyObject *, int, char **); +/* ssize_t-based buffer interface */ +typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); +typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); + +typedef int (*objobjproc)(PyObject *, PyObject *); +typedef int (*visitproc)(PyObject *, void *); +typedef int (*traverseproc)(PyObject *, visitproc, void *); + +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + +typedef struct { + /* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all + arguments are guaranteed to be of the object's type (modulo + coercion hacks -- i.e. if the type's coercion function + returns other types, then these are allowed as well). Numbers that + have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_divide; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_nonzero; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + coercion nb_coerce; + unaryfunc nb_int; + unaryfunc nb_long; + unaryfunc nb_float; + unaryfunc nb_oct; + unaryfunc nb_hex; + /* Added in release 2.0 */ + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_divide; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + /* Added in release 2.2 */ + /* The following require the Py_TPFLAGS_HAVE_CLASS flag */ + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + /* Added in release 2.5 */ + unaryfunc nb_index; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + ssizessizeargfunc sq_slice; + ssizeobjargproc sq_ass_item; + ssizessizeobjargproc sq_ass_slice; + objobjproc sq_contains; + /* Added in release 2.0 */ + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef struct { + readbufferproc bf_getreadbuffer; + writebufferproc bf_getwritebuffer; + segcountproc bf_getsegcount; + charbufferproc bf_getcharbuffer; + getbufferproc bf_getbuffer; + releasebufferproc bf_releasebuffer; +} PyBufferProcs; + + + +typedef struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "." */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + printfunc tp_print; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + cmpfunc tp_compare; + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Added in release 2.2 */ + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + struct PyMethodDef *tp_methods; + struct PyMemberDef *tp_members; + struct PyGetSetDef *tp_getset; + struct _typeobject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; + PyObject *tp_subclasses; + PyObject *tp_weaklist; + destructor tp_del; + + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + +} PyTypeObject; + +/* +`Type flags (tp_flags) + +These flags are used to extend the type structure in a backwards-compatible +fashion. Extensions can use the flags to indicate (and test) when a given +type structure contains a new feature. The Python core will use these when +introducing new functionality between major revisions (to avoid mid-version +changes in the PYTHON_API_VERSION). + +Arbitration of the flag bit positions will need to be coordinated among +all extension writers who publically release their extensions (this will +be fewer than you might expect!).. + +Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs. + +Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. + +Code can use PyType_HasFeature(type_ob, flag_value) to test whether the +given type object has a specified feature. + +NOTE: when building the core, Py_TPFLAGS_DEFAULT includes +Py_TPFLAGS_HAVE_VERSION_TAG; outside the core, it doesn't. This is so +that extensions that modify tp_dict of their own types directly don't +break, since this was allowed in 2.5. In 3.0 they will have to +manually remove this flag though! +*/ + +/* PyBufferProcs contains bf_getcharbuffer */ +#define Py_TPFLAGS_HAVE_GETCHARBUFFER (1L<<0) + +/* PySequenceMethods contains sq_contains */ +#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1) + +/* This is here for backwards compatibility. Extensions that use the old GC + * API will still compile but the objects will not be tracked by the GC. */ +#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */ + +/* PySequenceMethods and PyNumberMethods contain in-place operators */ +#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3) + +/* PyNumberMethods do their own coercion */ +#define Py_TPFLAGS_CHECKTYPES (1L<<4) + +/* tp_richcompare is defined */ +#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5) + +/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */ +#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6) + +/* tp_iter is defined */ +#define Py_TPFLAGS_HAVE_ITER (1L<<7) + +/* New members introduced by Python 2.2 exist */ +#define Py_TPFLAGS_HAVE_CLASS (1L<<8) + +/* Set if the type object is dynamically allocated */ +#define Py_TPFLAGS_HEAPTYPE (1L<<9) + +/* Set if the type allows subclassing */ +#define Py_TPFLAGS_BASETYPE (1L<<10) + +/* Set if the type is 'ready' -- fully initialized */ +#define Py_TPFLAGS_READY (1L<<12) + +/* Set while the type is being 'readied', to prevent recursive ready calls */ +#define Py_TPFLAGS_READYING (1L<<13) + +/* Objects support garbage collection (see objimp.h) */ +#define Py_TPFLAGS_HAVE_GC (1L<<14) + +/* These two bits are preserved for Stackless Python, next after this is 17 */ +#ifdef STACKLESS +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3L<<15) +#else +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 +#endif + +/* Objects support nb_index in PyNumberMethods */ +#define Py_TPFLAGS_HAVE_INDEX (1L<<17) + +/* Objects support type attribute cache */ +#define Py_TPFLAGS_HAVE_VERSION_TAG (1L<<18) +#define Py_TPFLAGS_VALID_VERSION_TAG (1L<<19) + +/* Type is abstract and cannot be instantiated */ +#define Py_TPFLAGS_IS_ABSTRACT (1L<<20) + +/* Has the new buffer protocol */ +#define Py_TPFLAGS_HAVE_NEWBUFFER (1L<<21) + +/* These flags are used to determine if a type is a subclass. */ +#define Py_TPFLAGS_INT_SUBCLASS (1L<<23) +#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24) +#define Py_TPFLAGS_LIST_SUBCLASS (1L<<25) +#define Py_TPFLAGS_TUPLE_SUBCLASS (1L<<26) +#define Py_TPFLAGS_STRING_SUBCLASS (1L<<27) +#define Py_TPFLAGS_UNICODE_SUBCLASS (1L<<28) +#define Py_TPFLAGS_DICT_SUBCLASS (1L<<29) +#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1L<<30) +#define Py_TPFLAGS_TYPE_SUBCLASS (1L<<31) + +#define Py_TPFLAGS_DEFAULT_EXTERNAL ( \ + Py_TPFLAGS_HAVE_GETCHARBUFFER | \ + Py_TPFLAGS_HAVE_SEQUENCE_IN | \ + Py_TPFLAGS_HAVE_INPLACEOPS | \ + Py_TPFLAGS_HAVE_RICHCOMPARE | \ + Py_TPFLAGS_HAVE_WEAKREFS | \ + Py_TPFLAGS_HAVE_ITER | \ + Py_TPFLAGS_HAVE_CLASS | \ + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_INDEX | \ + 0) +#define Py_TPFLAGS_DEFAULT_CORE (Py_TPFLAGS_DEFAULT_EXTERNAL | \ + Py_TPFLAGS_HAVE_VERSION_TAG) + +#define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL + + +/* objimpl.h ----------------------------------------------*/ + +PyObject * _PyObject_New(PyTypeObject *); +// PyVarObject * _PyObject_NewVar(PyTypeObject *, Py_ssize_t); + +#define PyObject_New(type, typeobj) \ + ( (type *) _PyObject_New(typeobj) ) +#define PyObject_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_NewVar((typeobj), (n)) ) + + +#endif Added: pypy/trunk/pypy/module/cpyext/include/stringobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/stringobject.h Sat Mar 20 19:42:35 2010 @@ -0,0 +1,15 @@ + +/* String object interface */ + +#ifndef Py_STRINGOBJECT_H +#define Py_STRINGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyObject * PyString_FromStringAndSize(const char *, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif Added: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/object.py Sat Mar 20 19:42:35 2010 @@ -0,0 +1,7 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.typeobject import PyTypeObjectPtr + + at cpython_api([PyTypeObjectPtr], PyObject) +def _PyObject_New(space, pto): + return space.wrap(42) Added: pypy/trunk/pypy/module/cpyext/stringobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/stringobject.py Sat Mar 20 19:42:35 2010 @@ -0,0 +1,13 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, Py_ssize_t + + at cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) +def PyString_FromStringAndSize(char_p, length): + l = [] + i = 0 + while length > 0: + l.append(cp[i]) + i += 1 + length -= 1 + return "".join(l) + Added: pypy/trunk/pypy/module/cpyext/test/foo.c ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/foo.c Sat Mar 20 19:42:35 2010 @@ -0,0 +1,142 @@ +#include "Python.h" + +typedef struct { + PyObject_HEAD + int foo; /* the context holder */ +} fooobject; + +static PyTypeObject footype; + +static fooobject * +newfooobject(void) +{ + fooobject *foop; + + foop = PyObject_New(fooobject, &footype); + if (foop == NULL) + return NULL; + + foop->foo = 42; + return foop; +} + + +/* foo methods */ + +static void +foo_dealloc(fooobject *foop) +{ + PyObject_Del(foop); +} + + +/* foo methods-as-attributes */ + +static PyObject * +foo_copy(fooobject *self) +{ + fooobject *foop; + + if ((foop = newfooobject()) == NULL) + return NULL; + + foop->foo = self->foo; + + return (PyObject *)foop; +} + + +static PyMethodDef foo_methods[] = { + {"copy", (PyCFunction)foo_copy, METH_NOARGS, NULL}, + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +foo_get_name(PyObject *self, void *closure) +{ + return PyString_FromStringAndSize("Foo Example", 11); +} + +static PyGetSetDef foo_getseters[] = { + {"name", + (getter)foo_get_name, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + + +static PyTypeObject footype = { + PyVarObject_HEAD_INIT(NULL, 0) + "foo.foo", /*tp_name*/ + sizeof(fooobject), /*tp_size*/ + 0, /*tp_itemsize*/ + /* methods */ + (destructor)foo_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + foo_methods, /*tp_methods*/ + 0, /*tp_members*/ + foo_getseters, /*tp_getset*/ +}; + + +/* foo functions */ + +static PyObject * +foo_new(PyObject *self, PyObject *args) +{ + fooobject *foop; + + if ((foop = newfooobject()) == NULL) { + return NULL; + } + + return (PyObject *)foop; +} + + +/* List of functions exported by this module */ + +static PyMethodDef foo_functions[] = { + {"new", (PyCFunction)foo_new, METH_NOARGS, NULL}, + {NULL, NULL} /* Sentinel */ +}; + + +/* Initialize this module. */ + +void initfoo(void) +{ + PyObject *m, *d; + + Py_TYPE(&footype) = &PyType_Type; + if (PyType_Ready(&footype) < 0) + return; + m = Py_InitModule("foo", foo_functions); + if (m == NULL) + return; + d = PyModule_GetDict(m); + PyDict_SetItemString(d, "fooType", (PyObject *)&footype); + /* No need to check the error here, the caller will do that */ +} Added: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sat Mar 20 19:42:35 2010 @@ -0,0 +1,12 @@ +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +import py +import sys + +class AppTestTypeObject(AppTestCpythonExtensionBase): + def test_typeobject(self): + skip("In progress") + import sys + module = self.import_module(name='foo') + assert 'foo' in sys.modules + assert module.new().name == "Foo Example" Added: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sat Mar 20 19:42:35 2010 @@ -0,0 +1,38 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject +from pypy.interpreter.module import Module +from pypy.module.cpyext.methodobject import PyCFunction_NewEx + +PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) + +PyTypeObject = cpython_struct( + "PyTypeObject", + []) +PyTypeObjectPtr = lltype.Ptr(PyTypeObject) + +def PyImport_AddModule(space, name): + w_name = space.wrap(name) + w_mod = space.wrap(Module(space, w_name)) + + w_modules = space.sys.get('modules') + space.setitem(w_modules, w_name, w_mod) + return w_mod + +#@cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) +def Py_InitModule(space, name, methods): + modname = rffi.charp2str(name) + w_mod = PyImport_AddModule(space, modname) + methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) + if methods: + i = 0 + while True: + method = methods[i] + if not method.c_ml_name: break + + methodname = rffi.charp2str(method.c_ml_name) + flags = method.c_ml_flags + w_function = PyCFunction_NewEx(space, method, None, modname) + space.setattr(w_mod, + space.wrap(methodname), + w_function) + i = i + 1 From arigo at codespeak.net Sat Mar 20 20:07:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 20:07:03 +0100 (CET) Subject: [pypy-svn] r72471 - in pypy/branch/rawffi-64/pypy/module/_rawffi: . test Message-ID: <20100320190703.48BA5282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 20:07:01 2010 New Revision: 72471 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Log: Fix the tests, and general progress. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 20:07:01 2010 @@ -45,7 +45,7 @@ return W_ArrayInstanceAutoFree(space, self, length) return W_ArrayInstance(space, self, length) - def get_ffi_type(self): + def get_basic_ffi_type(self): return self.basicffitype def descr_call(self, space, length, w_items=None, autofree=False): @@ -64,7 +64,9 @@ return space.wrap(result) def descr_repr(self, space): - return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % self.itemcode) + return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % (self.itemcode, + self.size, + self.alignment)) descr_repr.unwrap_spec = ['self', ObjSpace] def fromaddress(self, space, address, length): @@ -234,7 +236,7 @@ self._free() W_ArrayInstanceAutoFree.typedef = TypeDef( - 'ArrayInstanceWithFree', + 'ArrayInstanceAutoFree', __repr__ = interp2app(W_ArrayInstance.descr_repr), __setitem__ = interp2app(W_ArrayInstance.descr_setitem), __getitem__ = interp2app(W_ArrayInstance.descr_getitem), Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py Sat Mar 20 20:07:01 2010 @@ -65,9 +65,9 @@ self.w_callable = w_callable self.argshapes = unpack_argshapes(space, w_args) self.resshape = unpack_resshape(space, w_result) - ffiargs = [shape.get_ffi_type() for shape in self.argshapes] + ffiargs = [shape.get_basic_ffi_type() for shape in self.argshapes] if self.resshape is not None: - ffiresult = self.resshape.get_ffi_type() + ffiresult = self.resshape.get_basic_ffi_type() else: ffiresult = ffi_type_void # necessary to keep stuff alive Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py Sat Mar 20 20:07:01 2010 @@ -115,7 +115,7 @@ if isinstance(shape, W_Array) and length == 1: result = shape else: - ffitype = shape.get_ffi_type() + ffitype = shape.get_basic_ffi_type() size = shape.size * length result = W_Array(ffitype, size) shape._array_shapes[length] = result @@ -157,10 +157,12 @@ pass else: raise + # Array arguments not supported directly (in C, an array argument + # will be just a pointer). And the result cannot be an array (at all). argshapes = unpack_argshapes(space, w_argtypes) - ffi_argtypes = [shape.get_ffi_type() for shape in argshapes] + ffi_argtypes = [shape.get_basic_ffi_type() for shape in argshapes] if resshape is not None: - ffi_restype = resshape.get_ffi_type() + ffi_restype = resshape.get_basic_ffi_type() else: ffi_restype = ffi_type_void @@ -241,7 +243,7 @@ def allocate(self, space, length, autofree=False): raise NotImplementedError - def get_ffi_type(self): + def get_basic_ffi_type(self): raise NotImplementedError def descr_size_alignment(self, space, n=1): @@ -440,8 +442,8 @@ def descr_new_funcptr(space, w_tp, addr, w_args, w_res, flags=FUNCFLAG_CDECL): argshapes = unpack_argshapes(space, w_args) resshape = unpack_resshape(space, w_res) - ffi_args = [shape.get_ffi_type() for shape in argshapes] - ffi_res = resshape.get_ffi_type() + ffi_args = [shape.get_basic_ffi_type() for shape in argshapes] + ffi_res = resshape.get_basic_ffi_type() ptr = RawFuncPtr('???', ffi_args, ffi_res, rffi.cast(rffi.VOIDP, addr), flags) return space.wrap(W_FuncPtr(space, ptr, argshapes, resshape)) Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py Sat Mar 20 20:07:01 2010 @@ -14,6 +14,7 @@ from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length +from pypy.module._rawffi.interp_rawffi import size_alignment from pypy.rlib import libffi from pypy.rlib.rarithmetic import intmask, r_uint @@ -103,17 +104,32 @@ descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str] # get the corresponding ffi_type - ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO) + ffi_struct = lltype.nullptr(libffi.FFI_STRUCT_P.TO) - def get_ffi_type(self): - if not self.ffi_type: - self.ffi_type = libffi.make_struct_ffitype(self.size, - self.alignment) - return self.ffi_type + def get_basic_ffi_type(self): + if not self.ffi_struct: + # Repeated fields are delicate. Consider for example + # struct { int a[5]; } + # or struct { struct {int x;} a[5]; } + # Seeing no corresponding doc in libffi, let's just repeat + # the field 5 times... + fieldtypes = [] + for name, tp in self.fields: + basic_ffi_type = tp.get_basic_ffi_type() + basic_size, _ = size_alignment(basic_ffi_type) + total_size = tp.size + count = 0 + while count + basic_size <= total_size: + fieldtypes.append(basic_ffi_type) + count += basic_size + self.ffi_struct = libffi.make_struct_ffitype_e(self.size, + self.alignment, + fieldtypes) + return self.ffi_struct.ffistruct def __del__(self): - if self.ffi_type: - lltype.free(self.ffi_type, flavor='raw') + if self.ffi_struct: + lltype.free(self.ffi_struct, flavor='raw') Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Sat Mar 20 20:07:01 2010 @@ -145,10 +145,15 @@ int bah[2]; }; - struct s2a perturbarray(struct s2a inp) { - inp.bah[0] *= 4; - inp.bah[1] *= 5; - return inp; + struct s2a get_s2a(void) { + struct s2a outp; + outp.bah[0] = 4; + outp.bah[1] = 5; + return outp; + } + + int check_s2a(struct s2a inp) { + return (inp.bah[0] == 4 && inp.bah[1] == 5); } int AAA_first_ordinal_function() @@ -167,7 +172,7 @@ allocate_array static_int static_double sum_x_y - give perturb perturbarray + give perturb get_s2a check_s2a AAA_first_ordinal_function """.split() eci = ExternalCompilationInfo(export_symbols=symbols) @@ -188,9 +193,6 @@ cls.w_libm_name = space.wrap('libm.so') if sys.platform == "darwin": cls.w_libm_name = space.wrap('libm.dylib') - import platform - cls.w_isx86_64 = space.wrap(platform.machine() == 'x86_64') - cls.w_sizes_and_alignments = space.wrap(dict( [(k, (v.c_size, v.c_alignment)) for k,v in TYPEMAP.iteritems()])) @@ -675,7 +677,7 @@ # fragile S = _rawffi.Structure([('x', 'c'), ('y', 'l')]) assert (repr(_rawffi.Array((S, 2))) == - "<_rawffi.Array 'V' (%d, %d)>" % (4*lsize, lsize)) + "<_rawffi.Array '?' (%d, %d)>" % (4*lsize, lsize)) assert (repr(_rawffi.Structure([('x', 'i'), ('yz', 'i')])) == "<_rawffi.Structure 'x' 'yz' (%d, %d)>" % (2*isize, isize)) @@ -829,11 +831,6 @@ assert 0, "Did not raise" def test_struct_byvalue(self): - #if self.isx86_64: - # skip("Segfaults on x86_64 because small structures " - # "may be passed in registers and " - # "c_elements must not be null") - import _rawffi, sys X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')]) x_y = X_Y() @@ -849,11 +846,6 @@ x_y.free() def test_ret_struct(self): - if self.isx86_64: - skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") - import _rawffi S2H = _rawffi.Structure([('x', 'h'), ('y', 'h')]) s2h = S2H() @@ -885,39 +877,18 @@ s2h.free() def test_ret_struct_containing_array(self): - if self.isx86_64: - skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") - import _rawffi AoI = _rawffi.Array('i') S2A = _rawffi.Structure([('bah', (AoI, 2))]) - s2a = S2A() lib = _rawffi.CDLL(self.lib_name) - perturbarray = lib.ptr('perturbarray', [(S2A, 1)], (S2A, 1)) - s2a.x = 100 - a2a.y = 200 - res = perturbarray(s2a) - assert isinstance(res, _rawffi.StructureInstanceAutoFree) - assert res.shape is S2H - assert res.x == 13 - assert res.y == 17 - a1.free() - a2.free() + get_s2a = lib.ptr('get_s2a', [], (S2A, 1)) + check_s2a = lib.ptr('check_s2a', [(S2A, 1)], 'i') - s2h.x = 7 - s2h.y = 11 - perturb = lib.ptr('perturb', [(S2H, 1)], (S2H, 1)) - res = perturb(s2h) + res = get_s2a() assert isinstance(res, _rawffi.StructureInstanceAutoFree) - assert res.shape is S2H - assert res.x == 14 - assert res.y == 33 - assert s2h.x == 7 - assert s2h.y == 11 - - s2h.free() + assert res.shape is S2A + ok = check_s2a(res) + assert ok[0] == 1 def test_buffer(self): import _rawffi From arigo at codespeak.net Sat Mar 20 20:07:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 20:07:57 +0100 (CET) Subject: [pypy-svn] r72472 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320190757.E93D3282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 20:07:56 2010 New Revision: 72472 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Log: Last fixes? Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 20:07:56 2010 @@ -154,13 +154,13 @@ getlength.unwrap_spec = ['self', ObjSpace] def descr_itemaddress(self, space, num): - _, itemsize, _ = self.shape.itemtp + itemsize = self.shape.size ptr = rffi.ptradd(self.ll_buffer, itemsize * num) return space.wrap(rffi.cast(lltype.Unsigned, ptr)) descr_itemaddress.unwrap_spec = ['self', ObjSpace, int] def getrawsize(self): - _, itemsize, _ = self.shape.itemtp + itemsize = self.shape.size return itemsize * self.length def decodeslice(self, space, w_slice): From arigo at codespeak.net Sat Mar 20 20:16:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 20:16:16 +0100 (CET) Subject: [pypy-svn] r72473 - in pypy/branch/rawffi-64/pypy/module/_rawffi: . test Message-ID: <20100320191616.5DE51282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 20:16:14 2010 New Revision: 72473 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Log: Test and fix. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py Sat Mar 20 20:16:14 2010 @@ -10,6 +10,7 @@ wrap_value, unwrap_value, unwrap_truncate_int, \ unpack_argshapes, unpack_resshape from pypy.rlib.libffi import USERDATA_P, CallbackFuncPtr, FUNCFLAG_CDECL +from pypy.rlib.libffi import ffi_type_void from pypy.module._rawffi.tracker import tracker from pypy.interpreter.error import OperationError from pypy.interpreter import gateway Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py Sat Mar 20 20:16:14 2010 @@ -550,6 +550,22 @@ a1.free() del cb + def test_void_returning_callback(self): + import _rawffi + lib = _rawffi.CDLL(self.lib_name) + runcallback = lib.ptr('runcallback', ['P'], None) + called = [] + def callback(): + called.append(True) + + cb = _rawffi.CallbackPtr(callback, [], None) + a1 = cb.byptr() + res = runcallback(a1) + assert res is None + assert called == [True] + a1.free() + del cb + def test_another_callback_in_stackless(self): try: import _stackless From jandem at codespeak.net Sat Mar 20 20:44:29 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 20:44:29 +0100 (CET) Subject: [pypy-svn] r72474 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320194429.B6B74282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 20:44:27 2010 New Revision: 72474 Added: pypy/trunk/pypy/module/cpyext/boolobject.py Modified: pypy/trunk/pypy/module/cpyext/TODO pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Log: Add PyBool_FromLong and increment refcount in make_ref Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Sat Mar 20 20:44:27 2010 @@ -1,3 +1,4 @@ - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject - Add exceptions - Generate header files programmatically. + - Fix the '#define long int' hack in both api.py and include/Python.h Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sat Mar 20 20:44:27 2010 @@ -26,6 +26,7 @@ space.wrap(state.api_lib)) # import these modules to register api functions by side-effect +import pypy.module.cpyext.boolobject import pypy.module.cpyext.floatobject import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 20:44:27 2010 @@ -78,6 +78,8 @@ py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj + else: + py_obj.c_refcnt += 1 return py_obj def from_ref(space, ref): Added: pypy/trunk/pypy/module/cpyext/boolobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/boolobject.py Sat Mar 20 20:44:27 2010 @@ -0,0 +1,8 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject + + at cpython_api([rffi.LONG], PyObject) +def PyBool_FromLong(space, value): + if value != 0: + return space.w_True + return space.w_False Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sat Mar 20 20:44:27 2010 @@ -11,6 +11,8 @@ extern PyObject *PyPy_None; #define Py_None PyPy_None +#define long int /* XXX: same hack as in api.py */ + #include #include "boolobject.h" Modified: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Sat Mar 20 20:44:27 2010 @@ -17,6 +17,8 @@ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +PyObject* PyBool_FromLong(long); + #ifdef __cplusplus } #endif Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Sat Mar 20 20:44:27 2010 @@ -19,9 +19,27 @@ { Py_RETURN_FALSE; } + static PyObject* foo_test_FromLong(PyObject* self, PyObject *args) + { + int i; + for(i=-3; i<3; i++) + { + PyObject* obj = PyBool_FromLong(i); + PyObject* expected = (i ? Py_True : Py_False); + + if(obj != expected) + { + Py_DECREF(obj); + Py_RETURN_FALSE; + } + Py_DECREF(obj); + } + Py_RETURN_TRUE; + } static PyMethodDef methods[] = { { "get_true", foo_get_true, METH_NOARGS }, { "get_false", foo_get_false, METH_NOARGS }, + { "test_FromLong", foo_test_FromLong, METH_NOARGS }, { NULL } }; """ @@ -29,3 +47,4 @@ assert 'foo' in sys.modules assert module.get_true() == True assert module.get_false() == False + assert module.test_FromLong() == True From arigo at codespeak.net Sat Mar 20 21:00:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 21:00:29 +0100 (CET) Subject: [pypy-svn] r72475 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320200029.781F9282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 21:00:28 2010 New Revision: 72475 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Log: This assert can fail. Unsure if it's saner to have a W_Array with size=0 or to say that arrays 'T[0]' have size 1... Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py Sat Mar 20 21:00:28 2010 @@ -35,7 +35,6 @@ # the type of pointers to arrays of T. So the following fields # are used to describe T only. It is 'basicffitype' possibly # repeated until reaching the length 'size'. - assert size > 0 self.basicffitype = basicffitype self.size = size self.alignment = size_alignment(basicffitype)[1] From xoraxax at codespeak.net Sat Mar 20 21:12:29 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 21:12:29 +0100 (CET) Subject: [pypy-svn] r72476 - pypy/trunk/pypy/module/cpyext Message-ID: <20100320201229.DAAA2282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 21:12:05 2010 New Revision: 72476 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: Add declarations to typeobject.py Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sat Mar 20 21:12:05 2010 @@ -42,10 +42,11 @@ return func return decorate -def cpython_struct(name, fields): +def cpython_struct(name, fields, forward=None): configname = name.replace(' ', '__') setattr(CConfig, configname, rffi_platform.Struct(name, fields)) - forward = lltype.ForwardReference() + if forward is None: + forward = lltype.ForwardReference() TYPES[configname] = forward return forward @@ -55,7 +56,8 @@ # It is important that these PyObjects are allocated in a raw fashion # Thus we cannot save a forward pointer to the wrapped object # So we need a forward and backward mapping in our State instance -PyObject = lltype.Ptr(cpython_struct('struct _object', [("refcnt", lltype.Signed)])) +PyObjectFields = (("refcnt", lltype.Signed), ) +PyObject = lltype.Ptr(cpython_struct('struct _object', PyObjectFields)) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sat Mar 20 21:12:05 2010 @@ -4,4 +4,4 @@ @cpython_api([PyTypeObjectPtr], PyObject) def _PyObject_New(space, pto): - return space.wrap(42) + return space.wrap(42) # XXX Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sat Mar 20 21:12:05 2010 @@ -1,22 +1,142 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject -from pypy.interpreter.module import Module -from pypy.module.cpyext.methodobject import PyCFunction_NewEx +from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void -PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, PyObjectFields, Py_ssize_t +from pypy.interpreter.module import Module +from pypy.module.cpyext.modsupport import PyMethodDef +PyTypeObject = lltype.ForwardReference() +PyTypeObjectPtr = lltype.Ptr(PyTypeObject) +PyCFunction = Ptr(FuncType([PyObject, PyObject], PyObject)) +P, FT, PyO = Ptr, FuncType, PyObject +PyOPtr = Ptr(lltype.Array(PyO, hints={'nolength': True})) + + +# XXX +PyNumberMethods = PySequenceMethods = PyMappingMethods = \ + PyBufferProcs = PyMemberDef = PyGetSetDef = rffi.VOIDP.TO + +freefunc = P(FT([rffi.VOIDP], Void)) +destructor = P(FT([PyO], Void)) +printfunc = P(FT([PyO, rffi.VOIDP, rffi.INT], rffi.INT)) +getattrfunc = P(FT([PyO, rffi.CCHARP], PyO)) +getattrofunc = P(FT([PyO, PyO], PyO)) +setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT)) +setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT)) +cmpfunc = P(FT([PyO, PyO], rffi.INT)) +reprfunc = P(FT([PyO], PyO)) +hashfunc = P(FT([PyO], lltype.Signed)) +richcmpfunc = P(FT([PyO, PyO, rffi.INT], PyO)) +getiterfunc = P(FT([PyO], PyO)) +iternextfunc = P(FT([PyO], PyO)) +descrgetfunc = P(FT([PyO, PyO, PyO], PyO)) +descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT)) +initproc = P(FT([PyO, PyO, PyO], rffi.INT)) +newfunc = P(FT([PyTypeObjectPtr, PyO, PyO], PyO)) +allocfunc = P(FT([PyTypeObjectPtr, Py_ssize_t], PyO)) +unaryfunc = P(FT([PyO], PyO)) +binaryfunc = P(FT([PyO, PyO], PyO)) +ternaryfunc = P(FT([PyO, PyO, PyO], PyO)) +inquiry = P(FT([PyO], rffi.INT)) +lenfunc = P(FT([PyO], Py_ssize_t)) +coercion = P(FT([PyOPtr, PyOPtr], rffi.INT)) +intargfunc = P(FT([PyO, rffi.INT], PyO)) +intintargfunc = P(FT([PyO, rffi.INT, rffi.INT], PyO)) +ssizeargfunc = P(FT([PyO, Py_ssize_t], PyO)) +ssizessizeargfunc = P(FT([PyO, Py_ssize_t, Py_ssize_t], PyO)) +intobjargproc = P(FT([PyO, rffi.INT, PyO], rffi.INT)) +intintobjargproc = P(FT([PyO, rffi.INT, rffi.INT, PyO], rffi.INT)) +ssizeobjargproc = P(FT([PyO, Py_ssize_t, PyO], rffi.INT)) +ssizessizeobjargproc = P(FT([PyO, Py_ssize_t, Py_ssize_t, PyO], rffi.INT)) +objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT)) + +objobjproc = P(FT([PyO, PyO], rffi.INT)) +visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT)) +traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT)) + +PyTypeObjectFields = [] +PyTypeObjectFields.extend(PyObjectFields) +PyTypeObjectFields.extend([ + ("tp_name", rffi.CCHARP), # For printing, in format "." + ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation + + # Methods to implement standard operations + ("tp_dealloc", destructor), + ("tp_print", printfunc), + ("tp_getattr", getattrfunc), + ("tp_setattr", setattrfunc), + ("tp_compare", cmpfunc), + ("tp_repr", reprfunc), + + # Method suites for standard classes + ("tp_as_number", Ptr(PyNumberMethods)), + ("tp_as_sequence", Ptr(PySequenceMethods)), + ("tp_as_mapping", Ptr(PyMappingMethods)), + + # More standard operations (here for binary compatibility) + ("tp_hash", hashfunc), + ("tp_call", ternaryfunc), + ("tp_str", reprfunc), + ("tp_getattro", getattrofunc), + ("tp_setattro", setattrofunc), + + # Functions to access object as input/output buffer + ("tp_as_buffer", Ptr(PyBufferProcs)), + + # Flags to define presence of optional/expanded features + ("tp_flags", lltype.Signed), + + ("tp_doc", rffi.CCHARP), # Documentation string + + # Assigned meaning in release 2.0 + # call function for all accessible objects + ("tp_traverse", traverseproc), + + # delete references to contained objects + ("tp_clear", inquiry), + + # Assigned meaning in release 2.1 + # rich comparisons + ("tp_richcompare", richcmpfunc), + + # weak reference enabler + ("tp_weaklistoffset", Py_ssize_t), + + # Added in release 2.2 + # Iterators + ("tp_iter", getiterfunc), + ("tp_iternext", iternextfunc), + + # Attribute descriptor and subclassing stuff + ("tp_methods", Ptr(PyMethodDef)), + ("tp_members", Ptr(PyMemberDef)), + ("tp_getset", Ptr(PyGetSetDef)), + ("tp_base", Ptr(PyTypeObject)), + ("tp_dict", PyObject), + ("tp_descr_get", descrgetfunc), + ("tp_descr_set", descrsetfunc), + ("tp_dictoffset", Py_ssize_t), + ("tp_init", initproc), + ("tp_alloc", allocfunc), + ("tp_new", newfunc), + ("tp_free", freefunc), # Low-level free-memory routine + ("tp_is_gc", inquiry), # For PyObject_IS_GC + ("tp_bases", PyObject), + ("tp_mro", PyObject), # method resolution order + ("tp_cache", PyObject), + ("tp_subclasses", PyObject), + ("tp_weaklist", PyObject), + ("tp_del", destructor), + ]) +for x in PyTypeObjectFields: + try: + if len(x) != 2: + print x + except: + print x PyTypeObject = cpython_struct( "PyTypeObject", - []) -PyTypeObjectPtr = lltype.Ptr(PyTypeObject) - -def PyImport_AddModule(space, name): - w_name = space.wrap(name) - w_mod = space.wrap(Module(space, w_name)) - - w_modules = space.sys.get('modules') - space.setitem(w_modules, w_name, w_mod) - return w_mod + PyTypeObjectFields, PyTypeObject) #@cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) def Py_InitModule(space, name, methods): From arigo at codespeak.net Sat Mar 20 21:16:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Mar 2010 21:16:10 +0100 (CET) Subject: [pypy-svn] r72477 - pypy/branch/rawffi-64/pypy/module/_rawffi Message-ID: <20100320201610.1C318282BD4@codespeak.net> Author: arigo Date: Sat Mar 20 21:16:08 2010 New Revision: 72477 Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py Log: Partially revert the changes done here. This makes it more explicit that callbacks only support "simple" arguments, instead of accepting them in the constructor and crashing later. Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py ============================================================================== --- pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py (original) +++ pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py Sat Mar 20 21:16:08 2010 @@ -6,9 +6,8 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.module._rawffi.structure import unpack_fields from pypy.module._rawffi.array import get_elem, push_elem -from pypy.module._rawffi.interp_rawffi import W_DataInstance, \ - wrap_value, unwrap_value, unwrap_truncate_int, \ - unpack_argshapes, unpack_resshape +from pypy.module._rawffi.interp_rawffi import W_DataInstance, letter2tp, \ + wrap_value, unwrap_value, unwrap_truncate_int from pypy.rlib.libffi import USERDATA_P, CallbackFuncPtr, FUNCFLAG_CDECL from pypy.rlib.libffi import ffi_type_void from pypy.module._rawffi.tracker import tracker @@ -28,24 +27,24 @@ userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable - argshapes = callback_ptr.argshapes + args = callback_ptr.args space = callback_ptr.space try: # XXX The app-level callback gets the arguments as a list of integers. # Irregular interface here. Shows something, I say. w_args = space.newlist([space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) - for i in range(len(argshapes))]) + for i in range(len(args))]) w_res = space.call(w_callable, w_args) - if callback_ptr.resshape is not None: # don't return void + if callback_ptr.result is not None: # don't return void unwrap_value(space, push_elem, ll_res, 0, - callback_ptr.resshape.itemcode, w_res) + callback_ptr.result, w_res) except OperationError, e: tbprint(space, space.wrap(e.application_traceback), space.wrap(e.errorstr(space))) # force the result to be zero - if callback_ptr.resshape is not None: - size = callback_ptr.resshape.size - for i in range(size): + if callback_ptr.result is not None: + resshape = letter2tp(space, callback_ptr.result) + for i in range(resshape.size): ll_res[i] = '\x00' # XXX some weird hackery to be able to recover W_CallbackPtr object @@ -64,12 +63,14 @@ flags=FUNCFLAG_CDECL): self.space = space self.w_callable = w_callable - self.argshapes = unpack_argshapes(space, w_args) - self.resshape = unpack_resshape(space, w_result) - ffiargs = [shape.get_basic_ffi_type() for shape in self.argshapes] - if self.resshape is not None: - ffiresult = self.resshape.get_basic_ffi_type() + self.args = [space.str_w(w_arg) for w_arg in space.unpackiterable( + w_args)] + ffiargs = [letter2tp(space, x).get_basic_ffi_type() for x in self.args] + if not space.is_w(w_result, space.w_None): + self.result = space.str_w(w_result) + ffiresult = letter2tp(space, self.result).get_basic_ffi_type() else: + self.result = None ffiresult = ffi_type_void # necessary to keep stuff alive number = global_counter.CallbackPtr_id From dan at codespeak.net Sat Mar 20 21:48:23 2010 From: dan at codespeak.net (dan at codespeak.net) Date: Sat, 20 Mar 2010 21:48:23 +0100 (CET) Subject: [pypy-svn] r72478 - pypy/branch/interplevel-ctypes Message-ID: <20100320204823.23BE1282BD4@codespeak.net> Author: dan Date: Sat Mar 20 21:48:21 2010 New Revision: 72478 Added: pypy/branch/interplevel-ctypes/ - copied from r72477, pypy/trunk/ Log: Going to explore moving ctypes to interplevel. From xoraxax at codespeak.net Sat Mar 20 22:49:10 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 20 Mar 2010 22:49:10 +0100 (CET) Subject: [pypy-svn] r72480 - in pypy/trunk/pypy: rpython/lltypesystem translator/c translator/c/test Message-ID: <20100320214910.C3AF5282BD4@codespeak.net> Author: xoraxax Date: Sat Mar 20 22:49:09 2010 New Revision: 72480 Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/test/test_database.py Log: Add real void* type! Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py Sat Mar 20 22:49:09 2010 @@ -520,6 +520,7 @@ # void * - for now, represented as char * VOIDP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True})) +VOIDP_real = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True, 'render_as_void': True})) # void ** VOIDPP = CArrayPtr(VOIDP) Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Sat Mar 20 22:49:09 2010 @@ -304,7 +304,10 @@ self.LLTYPE = ARRAY self.varlength = varlength self.dependencies = {} - self.itemtypename = db.gettype(ARRAY.OF, who_asks=self) + contained_type = ARRAY.OF + if ARRAY._hints.get("render_as_void"): + contained_type = Void + self.itemtypename = db.gettype(contained_type, who_asks=self) def setup(self): """Array loops are forbidden by ForwardReference.become() because Modified: pypy/trunk/pypy/translator/c/test/test_database.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_database.py (original) +++ pypy/trunk/pypy/translator/c/test/test_database.py Sat Mar 20 22:49:09 2010 @@ -5,6 +5,7 @@ from pypy.objspace.flow.model import Constant, Variable, SpaceOperation from pypy.objspace.flow.model import Block, Link, FunctionGraph from pypy.rpython.typesystem import getfunctionptr +from pypy.rpython.lltypesystem.rffi import VOIDP_real def dump_on_stdout(database): @@ -221,6 +222,11 @@ db.complete() dump_on_stdout(db) +def test_voidp(): + A = VOIDP_real + db = LowLevelDatabase() + assert db.gettype(A) == "void *@" + def test_recursive_struct(): S = GcForwardReference() S.become(GcStruct('testing', ('p', Ptr(S)))) From jandem at codespeak.net Sat Mar 20 23:10:11 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Sat, 20 Mar 2010 23:10:11 +0100 (CET) Subject: [pypy-svn] r72481 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320221011.C0074282BD4@codespeak.net> Author: jandem Date: Sat Mar 20 23:10:09 2010 New Revision: 72481 Modified: pypy/trunk/pypy/module/cpyext/boolobject.py pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Log: Add PyBool_Check, the last PyBool_* function. Modified: pypy/trunk/pypy/module/cpyext/boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/boolobject.py Sat Mar 20 23:10:09 2010 @@ -1,6 +1,12 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject + at cpython_api([PyObject], rffi.INT) +def PyBool_Check(space, w_obj): + if space.eq_w(space.type(w_obj), space.w_bool): + return 1 + return 0 + @cpython_api([rffi.LONG], PyObject) def PyBool_FromLong(space, value): if value != 0: Modified: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Sat Mar 20 23:10:09 2010 @@ -17,6 +17,7 @@ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False +int PyBool_Check(PyObject*); PyObject* PyBool_FromLong(long); #ifdef __cplusplus Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Sat Mar 20 23:10:09 2010 @@ -36,10 +36,25 @@ } Py_RETURN_TRUE; } + static PyObject* foo_test_Check(PyObject* self, PyObject *args) + { + int result = 0; + PyObject* f = PyFloat_FromDouble(1.0); + + if(PyBool_Check(Py_True) && + PyBool_Check(Py_False) && + !PyBool_Check(f)) + { + result = 1; + } + Py_DECREF(f); + return PyBool_FromLong(result); + } static PyMethodDef methods[] = { { "get_true", foo_get_true, METH_NOARGS }, { "get_false", foo_get_false, METH_NOARGS }, { "test_FromLong", foo_test_FromLong, METH_NOARGS }, + { "test_Check", foo_test_Check, METH_NOARGS }, { NULL } }; """ @@ -48,3 +63,4 @@ assert module.get_true() == True assert module.get_false() == False assert module.test_FromLong() == True + assert module.test_Check() == True From xoraxax at codespeak.net Sun Mar 21 00:02:56 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 00:02:56 +0100 (CET) Subject: [pypy-svn] r72482 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320230256.1617F282BD4@codespeak.net> Author: xoraxax Date: Sun Mar 21 00:02:54 2010 New Revision: 72482 Added: pypy/trunk/pypy/module/cpyext/include/typeobject.c Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/modsupport.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/macros.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/test/foo.c pypy/trunk/pypy/module/cpyext/test/test_cpyext.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: Major extension, no new features. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 00:02:54 2010 @@ -14,10 +14,12 @@ from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError + Py_ssize_t = lltype.Signed +include_dir = py.path.local(autopath.pypydir).join('module', 'cpyext', 'include') include_dirs = [ - py.path.local(autopath.pypydir).join('module', 'cpyext', 'include'), + include_dir, udir, ] @@ -27,16 +29,29 @@ includes=['Python.h'] ) +class CConfig_constants: + _compilation_info_ = CConfig._compilation_info_ + +constant_names = """Py_TPFLAGS_READY Py_TPFLAGS_READYING """.split() +for name in constant_names: + setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) +# XXX does not work, why? +#globals().update(rffi_platform.configure(CConfig_constants)) +Py_TPFLAGS_READY = (1L<<12) +Py_TPFLAGS_READYING = (1L<<13) + + class ApiFunction: - def __init__(self, argtypes, restype, callable): + def __init__(self, argtypes, restype, callable, borrowed): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) self.callable = callable + self.borrowed = borrowed -def cpython_api(argtypes, restype): +def cpython_api(argtypes, restype, borrowed=False): def decorate(func): - api_function = ApiFunction(argtypes, restype, func) + api_function = ApiFunction(argtypes, restype, func, borrowed) FUNCTIONS[func.func_name] = api_function func.api_func = api_function return func @@ -56,12 +71,15 @@ # It is important that these PyObjects are allocated in a raw fashion # Thus we cannot save a forward pointer to the wrapped object # So we need a forward and backward mapping in our State instance -PyObjectFields = (("refcnt", lltype.Signed), ) -PyObject = lltype.Ptr(cpython_struct('struct _object', PyObjectFields)) +PyObjectStruct = lltype.ForwardReference() +PyObject = lltype.Ptr(PyObjectStruct) +PyObjectFields = (("obj_refcnt", lltype.Signed), ("obj_type", PyObject)) +cpython_struct('struct _object', PyObjectFields, PyObjectStruct) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): - TYPES[name].become(TYPE) + if name in TYPES: + TYPES[name].become(TYPE) class NullPointerException(Exception): pass @@ -69,19 +87,23 @@ class InvalidPointerException(Exception): pass -def make_ref(space, w_obj): +def make_ref(space, w_obj, borrowed=False): state = space.fromcache(State) py_obj = state.py_objects_w2r.get(w_obj) if py_obj is None: - py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") - py_obj.c_refcnt = 1 + if space.is_w(space.type(w_obj), space.w_type): + from pypy.module.cpyext.typeobject import allocate_type_obj + py_obj = allocate_type_obj(space, w_obj) + else: + py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + py_obj.c_obj_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj - else: - py_obj.c_refcnt += 1 + elif not borrowed: + py_obj.c_obj_refcnt += 1 return py_obj def from_ref(space, ref): @@ -158,6 +180,7 @@ PyObject *PyPy_True = NULL; PyObject *PyPy_False = NULL; PyObject *PyPyExc_Exception = NULL; + PyTypeObject *PyPyType_Type = NULL; """ code = (prologue + struct_declaration_code + @@ -169,6 +192,7 @@ eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], + #separate_module_files=[include_dir / "typeobject.c"], export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() @@ -180,10 +204,16 @@ import ctypes bridge = ctypes.CDLL(str(modulename)) pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') - Py_NONE = ctypes.c_void_p.in_dll(bridge, 'PyPy_None') - Py_TRUE = ctypes.c_void_p.in_dll(bridge, 'PyPy_True') - Py_FALSE = ctypes.c_void_p.in_dll(bridge, 'PyPy_False') - PyExc_Exception = ctypes.c_void_p.in_dll(bridge, 'PyPyExc_Exception') + + # populate static data + for name, w_obj in [("PyPy_None", space.w_None), + ("PyPy_True", space.w_True), + ("PyPy_False", space.w_False), + ("PyPyExc_Exception", space.w_Exception), + ("PyPyType_Type", space.w_type)]: + ptr = ctypes.c_void_p.in_dll(bridge, name) + ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), + ctypes.c_void_p).value def make_wrapper(callable): def wrapper(*args): @@ -210,7 +240,7 @@ return -1 assert False, "Unknown return type" if callable.api_func.restype is PyObject: - retval = make_ref(space, retval) + retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) return retval return wrapper @@ -219,14 +249,6 @@ pypyAPI[structindex[name]] = ctypes.cast( ll2ctypes.lltype2ctypes(llhelper(func.functype, make_wrapper(func.callable))), ctypes.c_void_p) - Py_NONE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_None)), - ctypes.c_void_p).value - Py_TRUE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_True)), - ctypes.c_void_p).value - Py_FALSE.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, space.w_False)), - ctypes.c_void_p).value - PyExc_Exception.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, - space.w_Exception)), ctypes.c_void_p).value return modulename.new(ext='') Modified: pypy/trunk/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/trunk/pypy/module/cpyext/include/modsupport.h Sun Mar 21 00:02:54 2010 @@ -7,7 +7,7 @@ extern "C" { #endif -void Py_InitModule(const char* name, PyMethodDef* methods); +PyObject *Py_InitModule(const char* name, PyMethodDef* methods); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sun Mar 21 00:02:54 2010 @@ -3,25 +3,36 @@ #include -typedef struct _object { - long refcnt; -} PyObject; typedef void* Py_buffer; + #define PyObject_HEAD \ - long refcnt; + long obj_refcnt; \ + struct _object *obj_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ - Py_ssize_t ob_size; /* Number of items in variable part */ + Py_ssize_t obj_size; /* Number of items in variable part */ #define PyObject_HEAD_INIT(type) \ - 1, /* XXX type, */ + 1, type, #define PyVarObject_HEAD_INIT(type, size) \ PyObject_HEAD_INIT(type) size, +typedef struct _object { + PyObject_HEAD +} PyObject; + +typedef struct { + PyObject_VAR_HEAD +} PyVarObject; + +#define Py_REFCNT(ob) (((PyObject*)(ob))->obj_refcnt) +#define Py_TYPE(ob) (((PyObject*)(ob))->obj_type) +#define Py_SIZE(ob) (((PyVarObject*)(ob))->obj_size) + extern PyObject *PyPy_None; #define Py_None PyPy_None @@ -367,6 +378,11 @@ #define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL +extern PyTypeObject *PyPyType_Type; /* built-in 'type' */ +#define PyType_Type *PyPyType_Type +int PyPyType_Ready(PyTypeObject *); +#define PyType_Ready PyPyType_Ready + /* objimpl.h ----------------------------------------------*/ PyObject * _PyObject_New(PyTypeObject *); @@ -377,5 +393,6 @@ #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) +void PyObject_Del(void *); #endif Added: pypy/trunk/pypy/module/cpyext/include/typeobject.c ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/typeobject.c Sun Mar 21 00:02:54 2010 @@ -0,0 +1,175 @@ +#include +#include + +int +PyPyType_Ready(PyTypeObject *type) +{ + PyObject *dict, *bases; + PyTypeObject *base; + Py_ssize_t i, n; + + if (type->tp_flags & Py_TPFLAGS_READY) { + assert(type->tp_dict != NULL); + return 0; + } + assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); + + type->tp_flags |= Py_TPFLAGS_READYING; + +#ifdef Py_TRACE_REFS + /* PyType_Ready is the closest thing we have to a choke point + * for type objects, so is the best place I can think of to try + * to get type objects into the doubly-linked list of all objects. + * Still, not all type objects go thru PyType_Ready. + */ + _Py_AddToAllObjects((PyObject *)type, 0); +#endif + + /* Initialize tp_base (defaults to BaseObject unless that's us) */ + base = type->tp_base; + if (base == NULL && type != &PyBaseObject_Type) { + base = type->tp_base = &PyBaseObject_Type; + Py_INCREF(base); + } + + /* Now the only way base can still be NULL is if type is + * &PyBaseObject_Type. + */ + + /* Initialize the base class */ + if (base && base->tp_dict == NULL) { + if (PyType_Ready(base) < 0) + goto error; + } + + /* Initialize ob_type if NULL. This means extensions that want to be + compilable separately on Windows can call PyType_Ready() instead of + initializing the ob_type field of their type objects. */ + /* The test for base != NULL is really unnecessary, since base is only + NULL when type is &PyBaseObject_Type, and we know its ob_type is + not NULL (it's initialized to &PyType_Type). But coverity doesn't + know that. */ + if (Py_TYPE(type) == NULL && base != NULL) + Py_TYPE(type) = Py_TYPE(base); + + /* Initialize tp_bases */ + bases = type->tp_bases; + if (bases == NULL) { + if (base == NULL) + bases = PyTuple_New(0); + else + bases = PyTuple_Pack(1, base); + if (bases == NULL) + goto error; + type->tp_bases = bases; + } + + /* Initialize tp_dict */ + dict = type->tp_dict; + if (dict == NULL) { + dict = PyDict_New(); + if (dict == NULL) + goto error; + type->tp_dict = dict; + } + + /* Add type-specific descriptors to tp_dict */ + if (add_operators(type) < 0) + goto error; + if (type->tp_methods != NULL) { + if (add_methods(type, type->tp_methods) < 0) + goto error; + } + if (type->tp_members != NULL) { + if (add_members(type, type->tp_members) < 0) + goto error; + } + if (type->tp_getset != NULL) { + if (add_getset(type, type->tp_getset) < 0) + goto error; + } + + /* Calculate method resolution order */ + if (mro_internal(type) < 0) { + goto error; + } + + /* Inherit special flags from dominant base */ + if (type->tp_base != NULL) + inherit_special(type, type->tp_base); + + /* Initialize tp_dict properly */ + bases = type->tp_mro; + assert(bases != NULL); + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = 1; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b)) + inherit_slots(type, (PyTypeObject *)b); + } + + /* Sanity check for tp_free. */ + if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && + (type->tp_free == NULL || type->tp_free == PyObject_Del)) { + /* This base class needs to call tp_free, but doesn't have + * one, or its tp_free is for non-gc'ed objects. + */ + PyErr_Format(PyExc_TypeError, "type '%.100s' participates in " + "gc and is a base type but has inappropriate " + "tp_free slot", + type->tp_name); + goto error; + } + + /* if the type dictionary doesn't contain a __doc__, set it from + the tp_doc slot. + */ + if (PyDict_GetItemString(type->tp_dict, "__doc__") == NULL) { + if (type->tp_doc != NULL) { + PyObject *doc = PyString_FromString(type->tp_doc); + if (doc == NULL) + goto error; + PyDict_SetItemString(type->tp_dict, "__doc__", doc); + Py_DECREF(doc); + } else { + PyDict_SetItemString(type->tp_dict, + "__doc__", Py_None); + } + } + + /* Some more special stuff */ + base = type->tp_base; + if (base != NULL) { + if (type->tp_as_number == NULL) + type->tp_as_number = base->tp_as_number; + if (type->tp_as_sequence == NULL) + type->tp_as_sequence = base->tp_as_sequence; + if (type->tp_as_mapping == NULL) + type->tp_as_mapping = base->tp_as_mapping; + if (type->tp_as_buffer == NULL) + type->tp_as_buffer = base->tp_as_buffer; + } + + /* Link into each base class's list of subclasses */ + bases = type->tp_bases; + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b) && + add_subclass((PyTypeObject *)b, type) < 0) + goto error; + } + + /* All done -- set the ready flag */ + assert(type->tp_dict != NULL); + type->tp_flags = + (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; + return 0; + + error: + type->tp_flags &= ~Py_TPFLAGS_READYING; + return -1; +} + + Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sun Mar 21 00:02:54 2010 @@ -9,20 +9,20 @@ def Py_DECREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) - obj.c_refcnt -= 1 - if obj.c_refcnt == 0: + obj.c_obj_refcnt -= 1 + if obj.c_obj_refcnt == 0: del state.py_objects_w2r[w_obj] ptr = ctypes.addressof(obj._obj._storage) del state.py_objects_r2w[ptr] # XXX this will likely be somewhere else when we have grown a type object lltype.free(obj, flavor='raw') else: - assert obj.c_refcnt > 0 + assert obj.c_obj_refcnt > 0 return @cpython_api([PyObject], lltype.Void) def Py_INCREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) - obj.c_refcnt += 1 + obj.c_obj_refcnt += 1 return Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 00:02:54 2010 @@ -20,7 +20,7 @@ space.setitem(w_modules, w_name, w_mod) return w_mod - at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) + at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], PyObject, borrowed=True) def Py_InitModule(space, name, methods): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) @@ -38,3 +38,4 @@ space.wrap(methodname), w_function) i = i + 1 + return w_mod Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sun Mar 21 00:02:54 2010 @@ -5,3 +5,7 @@ @cpython_api([PyTypeObjectPtr], PyObject) def _PyObject_New(space, pto): return space.wrap(42) # XXX + + at cpython_api([rffi.VOIDP_real], lltype.Void) +def PyObject_Del(space, w_obj): + pass # XXX move lltype.free here Modified: pypy/trunk/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/foo.c (original) +++ pypy/trunk/pypy/module/cpyext/test/foo.c Sun Mar 21 00:02:54 2010 @@ -1,3 +1,4 @@ +#include "pypy_rename.h" #include "Python.h" typedef struct { Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sun Mar 21 00:02:54 2010 @@ -24,7 +24,6 @@ assert 'Py_InitModule' in api.FUNCTIONS assert api.FUNCTIONS['Py_InitModule'].argtypes == [ rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] - assert api.FUNCTIONS['Py_InitModule'].restype == lltype.Void def compile_module(modname, **kwds): eci = ExternalCompilationInfo( Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 00:02:54 2010 @@ -1,7 +1,8 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, PyObjectFields, Py_ssize_t +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject,\ + PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef @@ -128,31 +129,12 @@ ("tp_weaklist", PyObject), ("tp_del", destructor), ]) -for x in PyTypeObjectFields: - try: - if len(x) != 2: - print x - except: - print x PyTypeObject = cpython_struct( "PyTypeObject", PyTypeObjectFields, PyTypeObject) -#@cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], lltype.Void) -def Py_InitModule(space, name, methods): - modname = rffi.charp2str(name) - w_mod = PyImport_AddModule(space, modname) - methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) - if methods: - i = 0 - while True: - method = methods[i] - if not method.c_ml_name: break - - methodname = rffi.charp2str(method.c_ml_name) - flags = method.c_ml_flags - w_function = PyCFunction_NewEx(space, method, None, modname) - space.setattr(w_mod, - space.wrap(methodname), - w_function) - i = i + 1 +def allocate_type_obj(space, w_obj): + py_obj = lltype.malloc(PyTypeObject, None, flavor="raw") + return py_obj + + From benjamin at codespeak.net Sun Mar 21 00:05:57 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 21 Mar 2010 00:05:57 +0100 (CET) Subject: [pypy-svn] r72483 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100320230557.938A2282BD4@codespeak.net> Author: benjamin Date: Sun Mar 21 00:05:56 2010 New Revision: 72483 Modified: pypy/trunk/pypy/module/cpyext/boolobject.py (props changed) pypy/trunk/pypy/module/cpyext/include/boolobject.h (props changed) pypy/trunk/pypy/module/cpyext/include/descrobject.h (props changed) pypy/trunk/pypy/module/cpyext/include/object.h (props changed) pypy/trunk/pypy/module/cpyext/include/stringobject.h (props changed) pypy/trunk/pypy/module/cpyext/include/typeobject.c (props changed) pypy/trunk/pypy/module/cpyext/object.py (props changed) pypy/trunk/pypy/module/cpyext/stringobject.py (props changed) pypy/trunk/pypy/module/cpyext/test/foo.c (props changed) pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (props changed) pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (props changed) pypy/trunk/pypy/module/cpyext/typeobject.py (props changed) Log: set native eol From xoraxax at codespeak.net Sun Mar 21 01:18:52 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 01:18:52 +0100 (CET) Subject: [pypy-svn] r72484 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100321001852.1EE9E282B9C@codespeak.net> Author: xoraxax Date: Sun Mar 21 01:18:50 2010 New Revision: 72484 Added: pypy/trunk/pypy/module/cpyext/dictobject.py (contents, props changed) pypy/trunk/pypy/module/cpyext/include/dictobject.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/macros.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/tupleobject.h (contents, props changed) pypy/trunk/pypy/module/cpyext/include/varargwrapper.c (contents, props changed) pypy/trunk/pypy/module/cpyext/tupleobject.py (contents, props changed) Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/typeobject.c pypy/trunk/pypy/module/cpyext/macros.py Log: General progress. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sun Mar 21 01:18:50 2010 @@ -34,4 +34,6 @@ import pypy.module.cpyext.pyerrors import pypy.module.cpyext.typeobject import pypy.module.cpyext.object +import pypy.module.cpyext.tupleobject +import pypy.module.cpyext.dictobject api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 01:18:50 2010 @@ -181,6 +181,7 @@ PyObject *PyPy_False = NULL; PyObject *PyPyExc_Exception = NULL; PyTypeObject *PyPyType_Type = NULL; + PyTypeObject *PyPyBaseObject_Type = NULL; """ code = (prologue + struct_declaration_code + @@ -192,7 +193,8 @@ eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], - #separate_module_files=[include_dir / "typeobject.c"], + #separate_module_files=[include_dir / "typeobject.c", + # include_dir / "varargwrapper.c"], export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() @@ -210,7 +212,9 @@ ("PyPy_True", space.w_True), ("PyPy_False", space.w_False), ("PyPyExc_Exception", space.w_Exception), - ("PyPyType_Type", space.w_type)]: + ("PyPyType_Type", space.w_type), + ("PyPyBaseObject_Type", space.w_object), + ]: ptr = ctypes.c_void_p.in_dll(bridge, name) ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), ctypes.c_void_p).value Added: pypy/trunk/pypy/module/cpyext/dictobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/dictobject.py Sun Mar 21 01:18:50 2010 @@ -0,0 +1,4 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject + + Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sun Mar 21 01:18:50 2010 @@ -1,13 +1,15 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H +/* Compat stuff */ #include #include -typedef long Py_ssize_t; +#define Py_ssize_t long #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) #include "object.h" +/* move somewhere else */ extern PyObject *PyPy_None; #define Py_None PyPy_None @@ -24,5 +26,8 @@ #include "pyerrors.h" #include "stringobject.h" #include "descrobject.h" +#include "tupleobject.h" +#include "dictobject.h" +#include "macros.h" #endif Added: pypy/trunk/pypy/module/cpyext/include/dictobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/dictobject.h Sun Mar 21 01:18:50 2010 @@ -0,0 +1,14 @@ + +/* dict object interface */ + +#ifndef Py_DICTOBJECT_H +#define Py_DICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DICTOBJECT_H */ Added: pypy/trunk/pypy/module/cpyext/include/macros.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/macros.h Sun Mar 21 01:18:50 2010 @@ -0,0 +1,3 @@ +/* operate on PyObject* */ +void Py_INCREF(PyObject *); +void Py_DECREF(PyObject *); Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sun Mar 21 01:18:50 2010 @@ -380,6 +380,8 @@ extern PyTypeObject *PyPyType_Type; /* built-in 'type' */ #define PyType_Type *PyPyType_Type +extern PyTypeObject *PyPyBaseObject_Type; +#define PyBaseObject_Type *PyPyBaseObject_Type int PyPyType_Ready(PyTypeObject *); #define PyType_Ready PyPyType_Ready Added: pypy/trunk/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/tupleobject.h Sun Mar 21 01:18:50 2010 @@ -0,0 +1,16 @@ + +/* Tuple object interface */ + +#ifndef Py_TUPLEOBJECT_H +#define Py_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyObject * PyTuple_New(Py_ssize_t size); +PyObject * PyTuple_Pack(Py_ssize_t, ...); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ Modified: pypy/trunk/pypy/module/cpyext/include/typeobject.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/typeobject.c (original) +++ pypy/trunk/pypy/module/cpyext/include/typeobject.c Sun Mar 21 01:18:50 2010 @@ -1,6 +1,9 @@ +#include + #include #include + int PyPyType_Ready(PyTypeObject *type) { Added: pypy/trunk/pypy/module/cpyext/include/varargwrapper.c ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/include/varargwrapper.c Sun Mar 21 01:18:50 2010 @@ -0,0 +1,20 @@ +#include +#include +#include + +PyObject * PyTuple_Pack(Py_ssize_t size, ...) +{ + va_list ap; + PyObject *cur, *tuple; + int i; + + tuple = PyTuple_New(size); + va_start(ap, size); + for (i = 0; i < size; cur = va_arg(ap, PyObject*)) { + Py_INCREF(cur); + PyTuple_SetItem(tuple, i, cur); + } + va_end(ap); + return tuple; +} + Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sun Mar 21 01:18:50 2010 @@ -25,4 +25,3 @@ state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) obj.c_obj_refcnt += 1 - return Added: pypy/trunk/pypy/module/cpyext/tupleobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/tupleobject.py Sun Mar 21 01:18:50 2010 @@ -0,0 +1,13 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t +from pypy.objspace.std.tupleobject import W_TupleObject + + + at cpython_api([Py_ssize_t], PyObject) +def PyTuple_New(space, size): + return space.newtuple([space.w_None] * size) + + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT) +def PyTuple_SetItem(space, w_t, pos, w_obj): + assert isinstance(w_t, W_TupleObject) + w_t.wrappeditems[pos] = w_obj From xoraxax at codespeak.net Sun Mar 21 02:30:30 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 02:30:30 +0100 (CET) Subject: [pypy-svn] r72485 - pypy/trunk/pypy/translator/platform Message-ID: <20100321013030.C439F282B9C@codespeak.net> Author: xoraxax Date: Sun Mar 21 02:30:29 2010 New Revision: 72485 Modified: pypy/trunk/pypy/translator/platform/linux.py Log: Add -Wall to the linux compiler options. Modified: pypy/trunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/trunk/pypy/translator/platform/linux.py (original) +++ pypy/trunk/pypy/translator/platform/linux.py Sun Mar 21 02:30:29 2010 @@ -9,7 +9,7 @@ name = "linux" link_flags = ['-pthread', '-lrt'] - cflags = ['-O3', '-pthread', '-fomit-frame-pointer'] + cflags = ['-O3', '-pthread', '-fomit-frame-pointer', '-Wall'] standalone_only = [] shared_only = ['-fPIC'] so_ext = 'so' From xoraxax at codespeak.net Sun Mar 21 04:58:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 04:58:13 +0100 (CET) Subject: [pypy-svn] r72486 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100321035813.74AD6282B9C@codespeak.net> Author: xoraxax Date: Sun Mar 21 04:58:11 2010 New Revision: 72486 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/dictobject.py pypy/trunk/pypy/module/cpyext/include/dictobject.h pypy/trunk/pypy/module/cpyext/include/modsupport.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/tupleobject.h pypy/trunk/pypy/module/cpyext/include/typeobject.c pypy/trunk/pypy/module/cpyext/include/varargwrapper.c pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/pyerrors.py pypy/trunk/pypy/module/cpyext/state.py pypy/trunk/pypy/module/cpyext/test/foo.c pypy/trunk/pypy/module/cpyext/test/test_typeobject.py pypy/trunk/pypy/module/cpyext/tupleobject.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: General progress, not sure how to implement the object and type. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 04:58:11 2010 @@ -1,4 +1,5 @@ import ctypes +import sys import py @@ -180,6 +181,7 @@ PyObject *PyPy_True = NULL; PyObject *PyPy_False = NULL; PyObject *PyPyExc_Exception = NULL; + PyObject *PyPyExc_TypeError = NULL; PyTypeObject *PyPyType_Type = NULL; PyTypeObject *PyPyBaseObject_Type = NULL; """ @@ -193,8 +195,8 @@ eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], - #separate_module_files=[include_dir / "typeobject.c", - # include_dir / "varargwrapper.c"], + separate_module_files=[include_dir / "typeobject.c", + include_dir / "varargwrapper.c"], export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() @@ -212,6 +214,7 @@ ("PyPy_True", space.w_True), ("PyPy_False", space.w_False), ("PyPyExc_Exception", space.w_Exception), + ("PyPyExc_TypeError", space.w_TypeError), ("PyPyType_Type", space.w_type), ("PyPyBaseObject_Type", space.w_object), ]: @@ -223,26 +226,36 @@ def wrapper(*args): boxed_args = [] # XXX use unrolling_iterable here + print >>sys.stderr, callable for i, typ in enumerate(callable.api_func.argtypes): arg = args[i] if typ is PyObject: arg = from_ref(space, arg) boxed_args.append(arg) + state = space.fromcache(State) try: retval = callable(space, *boxed_args) + print "Callable worked" except OperationError, e: e.normalize_exception(space) - state = space.fromcache(State) state.exc_type = e.w_type state.exc_value = e.get_w_value(space) + except BaseException, e: + state.exc_type = space.w_SystemError + state.exc_value = space.wrap(str(e)) + import traceback + traceback.print_exc() + + if state.exc_value is not None: restype = callable.api_func.restype if restype is lltype.Void: return if restype is PyObject: - return lltype.nullptr(PyObject) - if restype is lltype.Signed: + return lltype.nullptr(PyObject.TO) + if restype in (lltype.Signed, rffi.INT): return -1 assert False, "Unknown return type" + if callable.api_func.restype is PyObject: retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) return retval Modified: pypy/trunk/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/dictobject.py (original) +++ pypy/trunk/pypy/module/cpyext/dictobject.py Sun Mar 21 04:58:11 2010 @@ -1,4 +1,25 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject +from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall + at cpython_api([], PyObject) +def PyDict_New(space): + return space.newdict() + at cpython_api([PyObject], rffi.INT) +def PyDict_Check(space, w_obj): + w_type = space.w_dict + w_obj_type = space.type(w_obj) + return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) + + + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT) +def PyDict_SetItemString(space, w_dict, key_ptr, w_obj): + if PyDict_Check(space, w_dict): + key = rffi.charp2str(key_ptr) + # our dicts dont have a standardized interface, so we need + # to go through the space + space.setitem(w_dict, space.wrap(key), w_obj) + return 0 + else: + PyErr_BadInternalCall() Modified: pypy/trunk/pypy/module/cpyext/include/dictobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/dictobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/dictobject.h Sun Mar 21 04:58:11 2010 @@ -7,6 +7,8 @@ extern "C" { #endif +PyObject * PyDict_New(void); +int PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/trunk/pypy/module/cpyext/include/modsupport.h Sun Mar 21 04:58:11 2010 @@ -8,6 +8,8 @@ #endif PyObject *Py_InitModule(const char* name, PyMethodDef* methods); +PyObject * PyModule_GetDict(PyObject *); + #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sun Mar 21 04:58:11 2010 @@ -387,7 +387,7 @@ /* objimpl.h ----------------------------------------------*/ -PyObject * _PyObject_New(PyTypeObject *); +PyObject * _PyObject_New(PyObject *); // PyVarObject * _PyObject_NewVar(PyTypeObject *, Py_ssize_t); #define PyObject_New(type, typeobj) \ @@ -397,4 +397,7 @@ void PyObject_Del(void *); +/* PyPy internal ----------------------------------- */ +int PyPyType_Register(PyTypeObject *); + #endif Modified: pypy/trunk/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/tupleobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/tupleobject.h Sun Mar 21 04:58:11 2010 @@ -9,6 +9,8 @@ PyObject * PyTuple_New(Py_ssize_t size); PyObject * PyTuple_Pack(Py_ssize_t, ...); +PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +#define PyTuple_Pack PyPyTuple_Pack #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/typeobject.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/typeobject.c (original) +++ pypy/trunk/pypy/module/cpyext/include/typeobject.c Sun Mar 21 04:58:11 2010 @@ -75,7 +75,7 @@ goto error; type->tp_dict = dict; } - +#if 0 /* Add type-specific descriptors to tp_dict */ if (add_operators(type) < 0) goto error; @@ -163,9 +163,14 @@ add_subclass((PyTypeObject *)b, type) < 0) goto error; } - +#endif /* All done -- set the ready flag */ assert(type->tp_dict != NULL); + + /* PYPY ADDITION */ + if (PyPyType_Register(type) < 0) + goto error; + type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; return 0; Modified: pypy/trunk/pypy/module/cpyext/include/varargwrapper.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/varargwrapper.c (original) +++ pypy/trunk/pypy/module/cpyext/include/varargwrapper.c Sun Mar 21 04:58:11 2010 @@ -2,7 +2,7 @@ #include #include -PyObject * PyTuple_Pack(Py_ssize_t size, ...) +PyObject * PyPyTuple_Pack(Py_ssize_t size, ...) { va_list ap; PyObject *cur, *tuple; @@ -10,9 +10,10 @@ tuple = PyTuple_New(size); va_start(ap, size); - for (i = 0; i < size; cur = va_arg(ap, PyObject*)) { + for (i = 0; i < size; cur = va_arg(ap, PyObject*), i++) { Py_INCREF(cur); - PyTuple_SetItem(tuple, i, cur); + if (PyTuple_SetItem(tuple, i, cur) < 0) + return NULL; } va_end(ap); return tuple; Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 04:58:11 2010 @@ -2,6 +2,7 @@ from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx +from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) @@ -39,3 +40,17 @@ w_function) i = i + 1 return w_mod + + at cpython_api([PyObject], rffi.INT) +def PyModule_Check(space, w_obj): + w_type = space.gettypeobject(Module.typedef) + w_obj_type = space.type(w_obj) + return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) + + at cpython_api([PyObject], PyObject) +def PyModule_GetDict(space, w_mod): + if PyModule_Check(space, w_mod): + assert isinstance(w_mod, Module) + return w_mod.getdict() + else: + PyErr_BadInternalCall() Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sun Mar 21 04:58:11 2010 @@ -1,10 +1,17 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref from pypy.module.cpyext.typeobject import PyTypeObjectPtr +from pypy.objspace.std.objectobject import W_ObjectObject - at cpython_api([PyTypeObjectPtr], PyObject) -def _PyObject_New(space, pto): - return space.wrap(42) # XXX +def get_cls_for_type_object(space, w_type): + if space.is_w(w_type, space.w_object): + return W_ObjectObject + assert False, "Please add more cases!" + + at cpython_api([PyObject], PyObject) +def _PyObject_New(space, w_type): + cls = get_cls_for_type_object(space, w_type) + return space.allocate_instance(cls, w_type) @cpython_api([rffi.VOIDP_real], lltype.Void) def PyObject_Del(space, w_obj): Modified: pypy/trunk/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/pyerrors.py (original) +++ pypy/trunk/pypy/module/cpyext/pyerrors.py Sun Mar 21 04:58:11 2010 @@ -2,9 +2,15 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, PyObject, make_ref + @cpython_api([PyObject, rffi.CCHARP], lltype.Void) def PyErr_SetString(space, w_type, message_ptr): message = rffi.charp2str(message_ptr) w_obj = space.call_function(w_type, space.wrap(message)) raise OperationError(w_type, w_obj) + + at cpython_api([], lltype.Void) +def PyErr_BadInternalCall(space): + raise OperationError(space.w_SystemError, space.wrap("Bad internal call!")) + Modified: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/state.py (original) +++ pypy/trunk/pypy/module/cpyext/state.py Sun Mar 21 04:58:11 2010 @@ -15,5 +15,6 @@ if exc_type is not None or exc_value is not None: self.exc_value = None self.exc_type = None - raise OperationError(exc_type, exc_value) + op_err = OperationError(exc_type, exc_value) + raise op_err Modified: pypy/trunk/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/foo.c (original) +++ pypy/trunk/pypy/module/cpyext/test/foo.c Sun Mar 21 04:58:11 2010 @@ -139,5 +139,5 @@ return; d = PyModule_GetDict(m); PyDict_SetItemString(d, "fooType", (PyObject *)&footype); - /* No need to check the error here, the caller will do that */ + /* No need to check the error here, the caller will do that */ } Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 04:58:11 2010 @@ -9,4 +9,5 @@ import sys module = self.import_module(name='foo') assert 'foo' in sys.modules + print module.fooType assert module.new().name == "Foo Example" Modified: pypy/trunk/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/tupleobject.py (original) +++ pypy/trunk/pypy/module/cpyext/tupleobject.py Sun Mar 21 04:58:11 2010 @@ -11,3 +11,4 @@ def PyTuple_SetItem(space, w_t, pos, w_obj): assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj + return 0 Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 04:58:11 2010 @@ -1,10 +1,16 @@ +import ctypes + from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void - +from pypy.interpreter.gateway import ObjSpace, W_Root +from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject,\ PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef +from pypy.module.cpyext.state import State PyTypeObject = lltype.ForwardReference() PyTypeObjectPtr = lltype.Ptr(PyTypeObject) @@ -133,8 +139,41 @@ "PyTypeObject", PyTypeObjectFields, PyTypeObject) + +class W_PyCTypeObject(Wrappable): + pass + +class W_PyCObject(Wrappable): + pass + + at unwrap_spec(ObjSpace, W_Root, W_Root) +def cobject_descr_getattr(space, w_obj, w_name): + name = space.str_w(w_name) + return w_name + + def allocate_type_obj(space, w_obj): py_obj = lltype.malloc(PyTypeObject, None, flavor="raw") return py_obj +def create_type_object(space, pto): + return space.gettypeobject(W_PyCTypeObject) + at cpython_api([PyTypeObjectPtr], rffi.INT) +def PyPyType_Register(space, pto): + state = space.fromcache(State) + ptr = ctypes.addressof(pto._obj._storage) + if ptr not in state.py_objects_r2w: + w_obj = create_type_object(space, pto) + state.py_objects_r2w[ptr] = w_obj + state.py_objects_w2r[w_obj] = pto + return 1 + +W_PyCObject.typedef = TypeDef( + 'C_object', + __getattr__ = interp2app(cobject_descr_getattr), + ) + +W_PyCTypeObject.typedef = TypeDef( + 'C_type' + ) From arigo at codespeak.net Sun Mar 21 12:12:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 12:12:06 +0100 (CET) Subject: [pypy-svn] r72487 - pypy/trunk/py/plugin Message-ID: <20100321111206.9D211282B90@codespeak.net> Author: arigo Date: Sun Mar 21 12:12:04 2010 New Revision: 72487 Modified: pypy/trunk/py/plugin/pytest_resultlog.py Log: Try to be safe against str(unicode-with-non-standard-chars). We got a few such crashes on the nightly builds. Modified: pypy/trunk/py/plugin/pytest_resultlog.py ============================================================================== --- pypy/trunk/py/plugin/pytest_resultlog.py (original) +++ pypy/trunk/py/plugin/pytest_resultlog.py Sun Mar 21 12:12:04 2010 @@ -68,15 +68,15 @@ else: code = report.shortrepr if code == 'x': - longrepr = str(report.longrepr) + longrepr = safestr(report.longrepr) elif code == 'P': longrepr = '' elif report.passed: longrepr = "" elif report.failed: - longrepr = str(report.longrepr) + longrepr = safestr(report.longrepr) elif report.skipped: - longrepr = str(report.longrepr.reprcrash.message) + longrepr = safestr(report.longrepr.reprcrash.message) self.log_outcome(report.item, code, longrepr) def pytest_collectreport(self, report): @@ -86,9 +86,16 @@ else: assert report.skipped code = "S" - longrepr = str(report.longrepr.reprcrash) + longrepr = safestr(report.longrepr.reprcrash) self.log_outcome(report.collector, code, longrepr) def pytest_internalerror(self, excrepr): path = excrepr.reprcrash.path - self.write_log_entry(path, '!', str(excrepr)) + self.write_log_entry(path, '!', safestr(excrepr)) + + +def safestr(x): + if isinstance(x, unicode): + return x.encode('utf-8') + else: + return str(x) From arigo at codespeak.net Sun Mar 21 12:14:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 12:14:33 +0100 (CET) Subject: [pypy-svn] r72488 - in pypy/trunk/pypy: interpreter/test module/thread/test rlib rlib/test rpython/lltypesystem rpython/module rpython/test rpython/tool translator/c translator/c/gcc translator/c/src translator/c/test translator/tool Message-ID: <20100321111433.42CAB282B90@codespeak.net> Author: arigo Date: Sun Mar 21 12:14:30 2010 New Revision: 72488 Added: pypy/trunk/pypy/translator/c/src/commondefs.h - copied unchanged from r72486, pypy/branch/kill-python-h/pypy/translator/c/src/commondefs.h Removed: pypy/trunk/pypy/rlib/getaddrinfo.py pypy/trunk/pypy/rlib/getnameinfo.py pypy/trunk/pypy/translator/c/src/addrinfo.h pypy/trunk/pypy/translator/c/src/getaddrinfo.c pypy/trunk/pypy/translator/c/src/getnameinfo.c Modified: pypy/trunk/pypy/interpreter/test/test_function.py pypy/trunk/pypy/module/thread/test/test_import_lock.py pypy/trunk/pypy/rlib/_rsocket_rffi.py pypy/trunk/pypy/rlib/rmmap.py pypy/trunk/pypy/rlib/rsocket.py pypy/trunk/pypy/rlib/test/test_rsocket.py pypy/trunk/pypy/rpython/lltypesystem/ll_str.py pypy/trunk/pypy/rpython/module/ll_os.py pypy/trunk/pypy/rpython/module/ll_os_stat.py pypy/trunk/pypy/rpython/module/ll_time.py pypy/trunk/pypy/rpython/test/test_rint.py pypy/trunk/pypy/rpython/tool/rffi_platform.py pypy/trunk/pypy/translator/c/gcc/trackgcroot.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/src/g_include.h pypy/trunk/pypy/translator/c/src/g_prerequisite.h pypy/trunk/pypy/translator/c/src/main.h pypy/trunk/pypy/translator/c/src/obmalloc.c pypy/trunk/pypy/translator/c/src/stack.h pypy/trunk/pypy/translator/c/src/support.h pypy/trunk/pypy/translator/c/src/thread.h pypy/trunk/pypy/translator/c/src/thread_pthread.h pypy/trunk/pypy/translator/c/test/test_dlltool.py pypy/trunk/pypy/translator/c/test/test_math.py pypy/trunk/pypy/translator/c/test/test_standalone.py pypy/trunk/pypy/translator/tool/cbuild.py Log: Merge branch/kill-python-h: Clean up the dependencies of the generated C files -- the main result is to remove the dependency on Python.h or pyconfig.h. 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 Sun Mar 21 12:14:30 2010 @@ -281,6 +281,14 @@ raises(TypeError, type, 'Foo', (type(f),), {}) raises(TypeError, type, 'Foo', (type(len),), {}) + def test_lambda_docstring(self): + # Like CPython, (lambda:"foo") has a docstring of "foo". + # But let's not test that. Just test that (lambda:42) does not + # have 42 as docstring. + f = lambda: 42 + assert f.func_doc is None + + class AppTestMethod: def test_simple_call(self): class A(object): Modified: pypy/trunk/pypy/module/thread/test/test_import_lock.py ============================================================================== --- pypy/trunk/pypy/module/thread/test/test_import_lock.py (original) +++ pypy/trunk/pypy/module/thread/test/test_import_lock.py Sun Mar 21 12:14:30 2010 @@ -10,17 +10,19 @@ cls.w_tmpdir = cls.space.wrap(tmpdir) def test_import_lock(self): + # XXX XXX XXX this test fails if run together with all other tests + # of this directory, but not when run alone import thread, imp assert not imp.lock_held() done = [] - def f(): + def f(i): print '[ENTER %d]' % i from imghdr import testall print '[LEAVE %d]' % i done.append(1) for i in range(5): print '[RUN %d]' % i - thread.start_new_thread(f, ()) + thread.start_new_thread(f, (i,)) self.waitfor(lambda: len(done) == 5) assert len(done) == 5 Modified: pypy/trunk/pypy/rlib/_rsocket_rffi.py ============================================================================== --- pypy/trunk/pypy/rlib/_rsocket_rffi.py (original) +++ pypy/trunk/pypy/rlib/_rsocket_rffi.py Sun Mar 21 12:14:30 2010 @@ -448,13 +448,12 @@ socketconnect = external('connect', [socketfd_type, sockaddr_ptr, socklen_t], rffi.INT) -if not WIN32: - getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP, - addrinfo_ptr, - lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT) - freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void) - getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, - size_t, CCHARP, size_t, rffi.INT], rffi.INT) +getaddrinfo = external('getaddrinfo', [CCHARP, CCHARP, + addrinfo_ptr, + lltype.Ptr(rffi.CArray(addrinfo_ptr))], rffi.INT) +freeaddrinfo = external('freeaddrinfo', [addrinfo_ptr], lltype.Void) +getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, + size_t, CCHARP, size_t, rffi.INT], rffi.INT) htonl = external('htonl', [rffi.UINT], rffi.UINT) htons = external('htons', [rffi.USHORT], rffi.USHORT) @@ -563,78 +562,14 @@ WSAGetLastError = external('WSAGetLastError', [], rffi.INT) geterrno = WSAGetLastError - - import errno - WIN32_ERROR_MESSAGES = { - errno.WSAEINTR: "Interrupted system call", - errno.WSAEBADF: "Bad file descriptor", - errno.WSAEACCES: "Permission denied", - errno.WSAEFAULT: "Bad address", - errno.WSAEINVAL: "Invalid argument", - errno.WSAEMFILE: "Too many open files", - errno.WSAEWOULDBLOCK: - "The socket operation could not complete without blocking", - errno.WSAEINPROGRESS: "Operation now in progress", - errno.WSAEALREADY: "Operation already in progress", - errno.WSAENOTSOCK: "Socket operation on non-socket", - errno.WSAEDESTADDRREQ: "Destination address required", - errno.WSAEMSGSIZE: "Message too long", - errno.WSAEPROTOTYPE: "Protocol wrong type for socket", - errno.WSAENOPROTOOPT: "Protocol not available", - errno.WSAEPROTONOSUPPORT: "Protocol not supported", - errno.WSAESOCKTNOSUPPORT: "Socket type not supported", - errno.WSAEOPNOTSUPP: "Operation not supported", - errno.WSAEPFNOSUPPORT: "Protocol family not supported", - errno.WSAEAFNOSUPPORT: "Address family not supported", - errno.WSAEADDRINUSE: "Address already in use", - errno.WSAEADDRNOTAVAIL: "Can't assign requested address", - errno.WSAENETDOWN: "Network is down", - errno.WSAENETUNREACH: "Network is unreachable", - errno.WSAENETRESET: "Network dropped connection on reset", - errno.WSAECONNABORTED: "Software caused connection abort", - errno.WSAECONNRESET: "Connection reset by peer", - errno.WSAENOBUFS: "No buffer space available", - errno.WSAEISCONN: "Socket is already connected", - errno.WSAENOTCONN: "Socket is not connected", - errno.WSAESHUTDOWN: "Can't send after socket shutdown", - errno.WSAETOOMANYREFS: "Too many references: can't splice", - errno.WSAETIMEDOUT: "Operation timed out", - errno.WSAECONNREFUSED: "Connection refused", - errno.WSAELOOP: "Too many levels of symbolic links", - errno.WSAENAMETOOLONG: "File name too long", - errno.WSAEHOSTDOWN: "Host is down", - errno.WSAEHOSTUNREACH: "No route to host", - errno.WSAENOTEMPTY: "Directory not empty", - errno.WSAEPROCLIM: "Too many processes", - errno.WSAEUSERS: "Too many users", - errno.WSAEDQUOT: "Disc quota exceeded", - errno.WSAESTALE: "Stale NFS file handle", - errno.WSAEREMOTE: "Too many levels of remote in path", - errno.WSASYSNOTREADY: "Network subsystem is unvailable", - errno.WSAVERNOTSUPPORTED: "WinSock version is not supported", - errno.WSANOTINITIALISED: "Successful WSAStartup() not yet performed", - errno.WSAEDISCON: "Graceful shutdown in progress", - - # Resolver errors - # XXX Not exported by errno. Replace by the values in winsock.h - # errno.WSAHOST_NOT_FOUND: "No such host is known", - # errno.WSATRY_AGAIN: "Host not found, or server failed", - # errno.WSANO_RECOVERY: "Unexpected server error encountered", - # errno.WSANO_DATA: "Valid name without requested data", - # errno.WSANO_ADDRESS: "No address, look for MX record", - - # select() errors - WSA_IO_PENDING: "WSA_IO_PENDING", - WSA_IO_INCOMPLETE: "WSA_IO_INCOMPLETE", - WSA_INVALID_HANDLE: "WSA_INVALID_HANDLE", - WSA_INVALID_PARAMETER: "WSA_INVALID_PARAMETER", - WSA_NOT_ENOUGH_MEMORY: "WSA_NOT_ENOUGH_MEMORY", - WSA_OPERATION_ABORTED: "WSA_OPERATION_ABORTED", - } - assert len(WIN32_ERROR_MESSAGES) == 53 # detect duplicates + from pypy.rlib import rwin32 def socket_strerror_str(errno): - return WIN32_ERROR_MESSAGES.get(errno, "winsock error %d" % errno) + return rwin32.FormatError(errno) + def gai_strerror_str(errno): + return rwin32.FormatError(errno) else: socket_strerror_str = os.strerror + def gai_strerror_str(errno): + return rffi.charp2str(gai_strerror(errno)) Modified: pypy/trunk/pypy/rlib/rmmap.py ============================================================================== --- pypy/trunk/pypy/rlib/rmmap.py (original) +++ pypy/trunk/pypy/rlib/rmmap.py Sun Mar 21 12:14:30 2010 @@ -32,9 +32,10 @@ class CConfig: _compilation_info_ = ExternalCompilationInfo( includes=includes, - pre_include_bits=['#ifndef _GNU_SOURCE\n' + - '#define _GNU_SOURCE\n' + - '#endif'] + #pre_include_bits=['#ifndef _GNU_SOURCE\n' + + # '#define _GNU_SOURCE\n' + + # '#endif'] + # ^^^ _GNU_SOURCE is always defined by the ExternalCompilationInfo now ) size_t = rffi_platform.SimpleType("size_t", rffi.LONG) off_t = rffi_platform.SimpleType("off_t", rffi.LONG) Modified: pypy/trunk/pypy/rlib/rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/rsocket.py (original) +++ pypy/trunk/pypy/rlib/rsocket.py Sun Mar 21 12:14:30 2010 @@ -1040,8 +1040,7 @@ class GAIError(SocketErrorWithErrno): applevelerrcls = 'gaierror' def get_msg(self): - # this method may be patched below - return rffi.charp2str(_c.gai_strerror(self.errno)) + return _c.gai_strerror_str(self.errno) class HSocketError(SocketError): applevelerrcls = 'herror' @@ -1334,17 +1333,3 @@ if timeout < 0.0: timeout = -1.0 defaults.timeout = timeout - -# _______________________________________________________________ -# -# Patch module, for platforms without getaddrinfo / getnameinfo -# - -if not getattr(_c, 'getaddrinfo', None): - from pypy.rlib.getaddrinfo import getaddrinfo - from pypy.rlib.getaddrinfo import GAIError_getmsg - GAIError.get_msg = GAIError_getmsg - -if not getattr(_c, 'getnameinfo', None): - from pypy.rlib.getnameinfo import getnameinfo - from pypy.rlib.getnameinfo import NI_NUMERICHOST, NI_NUMERICSERV Modified: pypy/trunk/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rsocket.py (original) +++ pypy/trunk/pypy/rlib/test/test_rsocket.py Sun Mar 21 12:14:30 2010 @@ -281,7 +281,8 @@ addr.get_port() == 80): found = True assert found, lst - py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', None) + e = py.test.raises(GAIError, getaddrinfo, 'www.very-invalidaddress.com', None) + assert isinstance(e.value.get_msg(), str) def test_getaddrinfo_codespeak(): lst = getaddrinfo('codespeak.net', None) Modified: pypy/trunk/pypy/rpython/lltypesystem/ll_str.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/ll_str.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/ll_str.py Sun Mar 21 12:14:30 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem.lltype import GcArray, Array, Char, malloc from pypy.rpython.annlowlevel import llstr -from pypy.rlib.rarithmetic import r_uint, formatd +from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, formatd CHAR_ARRAY = GcArray(Char) @@ -8,6 +8,12 @@ return ll_int2dec(i) ll_int_str._pure_function_ = True +def ll_unsigned(i): + if isinstance(i, r_longlong) or isinstance(i, r_ulonglong): + return r_ulonglong(i) + else: + return r_uint(i) + def ll_int2dec(i): from pypy.rpython.lltypesystem.rstr import mallocstr temp = malloc(CHAR_ARRAY, 20) @@ -15,9 +21,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) if i == 0: len = 1 temp[0] = '0' @@ -52,9 +58,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) if i == 0: len = 1 temp[0] = '0' @@ -94,9 +100,9 @@ sign = 0 if i < 0: sign = 1 - i = r_uint(-i) + i = ll_unsigned(-i) else: - i = r_uint(i) + i = ll_unsigned(i) while i: temp[len] = hex_chars[i & 0x7] i >>= 3 Modified: pypy/trunk/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_os.py (original) +++ pypy/trunk/pypy/rpython/module/ll_os.py Sun Mar 21 12:14:30 2010 @@ -88,31 +88,17 @@ def __init__(self): self.configure(CConfig) - # on some platforms, e.g. OS X Leopard, the following constants which - # may be defined in pyconfig.h triggers "legacy" behaviour for functions - # like setpgrp(): - # - # _POSIX_C_SOURCE 200112L - # _XOPEN_SOURCE 600 - # _DARWIN_C_SOURCE 1 - # - # since the translation currently includes pyconfig.h, the checkcompiles - # call below include the pyconfig.h file so that the same behaviour is - # present in both the check and the final translation... - if hasattr(os, 'getpgrp'): self.GETPGRP_HAVE_ARG = platform.checkcompiles( "getpgrp(0)", - '#include "pyconfig.h"\n#include ', - [platform.get_python_include_dir()] - ) + '#include ', + []) if hasattr(os, 'setpgrp'): self.SETPGRP_HAVE_ARG = platform.checkcompiles( "setpgrp(0,0)", - '#include "pyconfig.h"\n#include ', - [platform.get_python_include_dir()] - ) + '#include ', + []) # we need an indirection via c functions to get macro calls working on llvm XXX still? if hasattr(os, 'WCOREDUMP'): Modified: pypy/trunk/pypy/rpython/module/ll_os_stat.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_os_stat.py (original) +++ pypy/trunk/pypy/rpython/module/ll_os_stat.py Sun Mar 21 12:14:30 2010 @@ -136,7 +136,8 @@ compilation_info = ExternalCompilationInfo( # This must be set to 64 on some systems to enable large file support. - pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], + #pre_include_bits = ['#define _FILE_OFFSET_BITS 64'], + # ^^^ nowadays it's always set in all C files we produce. includes = INCLUDES ) Modified: pypy/trunk/pypy/rpython/module/ll_time.py ============================================================================== --- pypy/trunk/pypy/rpython/module/ll_time.py (original) +++ pypy/trunk/pypy/rpython/module/ll_time.py Sun Mar 21 12:14:30 2010 @@ -15,7 +15,8 @@ TIME_H = 'time.h' FTIME = '_ftime64' STRUCT_TIMEB = 'struct __timeb64' - includes = [TIME_H, 'windows.h', 'sys/types.h', 'sys/timeb.h'] + includes = ['winsock2.h', 'windows.h', + TIME_H, 'sys/types.h', 'sys/timeb.h'] else: TIME_H = 'sys/time.h' FTIME = 'ftime' Modified: pypy/trunk/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rint.py (original) +++ pypy/trunk/pypy/rpython/test/test_rint.py Sun Mar 21 12:14:30 2010 @@ -1,3 +1,4 @@ +import py import sys, operator from pypy.translator.translator import TranslationContext from pypy.annotation import model as annmodel @@ -105,6 +106,16 @@ res = self.ll_to_string(res) assert res == '-' + oct(sys.maxint+1).replace('L', '').replace('l', '') + def test_str_of_longlong(self): + def f(i): + return str(i) + + res = self.interpret(f, [r_longlong(0)]) + assert self.ll_to_string(res) == '0' + + res = self.interpret(f, [r_longlong(413974738222117)]) + assert self.ll_to_string(res) == '413974738222117' + def test_unsigned(self): bigvalue = sys.maxint + 17 def dummy(i): 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 Sun Mar 21 12:14:30 2010 @@ -8,7 +8,6 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import CompilationError from pypy.tool.udir import udir -import distutils # ____________________________________________________________ # @@ -18,7 +17,7 @@ if include_dirs is None: include_dirs = [] return ExternalCompilationInfo( - pre_include_bits=[c_header_source], + post_include_bits=[c_header_source], include_dirs=include_dirs ) @@ -563,11 +562,6 @@ # ____________________________________________________________ -def get_python_include_dir(): - from distutils import sysconfig - gcv = sysconfig.get_config_vars() - return gcv.get('INCLUDEPY', '.') # this is for running on top of pypy-c - def configure_external_library(name, eci, configurations, symbol=None, _cache={}): """try to find the external library. Modified: pypy/trunk/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/trunk/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/trunk/pypy/translator/c/gcc/trackgcroot.py Sun Mar 21 12:14:30 2010 @@ -331,6 +331,11 @@ label = label2 if label is None: k = call.lineno + if self.format == 'msvc': + # Some header files (ws2tcpip.h) define STDCALL functions + funcname = self.funcname.split('@')[0] + else: + funcname = self.funcname while 1: label = '__gcmap_%s__%s_%d' % (self.filetag, self.funcname, k) if label not in self.labels: Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Sun Mar 21 12:14:30 2010 @@ -115,12 +115,8 @@ 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] + include_dirs = [pypy_include_dir] return ExternalCompilationInfo(include_dirs=include_dirs) def build_database(self): @@ -306,6 +302,12 @@ _module = None _wrapper = None + def get_eci(self): + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() + eci = ExternalCompilationInfo(include_dirs=[python_inc]) + return eci.merge(CBuilder.get_eci(self)) + def getentrypointptr(self): # xxx if self._wrapper is None: self._wrapper = new_wrapper(self.entrypoint, self.translator) @@ -740,16 +742,7 @@ print >> f -def gen_size_check(f): - from pypy.rlib.rarithmetic import LONG_BIT - print >> f, '#if 8 * SIZEOF_LONG != %d' % (LONG_BIT,) - print >> f, '# error "C files are generated for a %d-bit platform"' % ( - LONG_BIT,) - print >> f, '#endif' - print >> f - def gen_structdef(f, database): - gen_size_check(f) structdeflist = database.getstructdeflist() print >> f, '/***********************************************************/' print >> f, '/*** Structure definitions ***/' @@ -835,6 +828,10 @@ print >> f, '\treturn error;' print >> f, '}' +def commondefs(defines): + from pypy.rlib.rarithmetic import LONG_BIT + defines['PYPY_LONG_BIT'] = LONG_BIT + def gen_source_standalone(database, modulename, targetdir, eci, entrypointname, defines={}): assert database.standalone @@ -850,16 +847,11 @@ # print >> f, '#include "common_header.h"' print >> f + commondefs(defines) defines['PYPY_STANDALONE'] = entrypointname for key, value in defines.items(): print >> fi, '#define %s %s' % (key, value) - if sys.platform == 'win32': - print >> fi, '#define Py_BUILD_CORE /* avoid pulling python libs in */' - print >> fi, '#define WIN32_LEAN_AND_MEAN /* winsock/winsock2 mess */' - - print >> fi, '#include "pyconfig.h"' - eci.write_c_header(fi) print >> fi, '#include "src/g_prerequisite.h"' @@ -907,14 +899,10 @@ # print >> f, '#include "common_header.h"' print >> f + commondefs(defines) for key, value in defines.items(): print >> fi, '#define %s %s' % (key, value) - if sys.platform == 'win32': - print >> fi, '#define WIN32_LEAN_AND_MEAN /* winsock/winsock2 mess */' - - print >> fi, '#include "pyconfig.h"' - eci.write_c_header(fi) print >> fi, '#include "src/g_prerequisite.h"' 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 Sun Mar 21 12:14:30 2010 @@ -54,9 +54,6 @@ #ifndef AVR # include "src/ll_os.h" # include "src/ll_strtod.h" -# ifdef RPyExc_thread_error -# include "src/ll_thread.h" -# endif #endif #endif Modified: pypy/trunk/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/trunk/pypy/translator/c/src/g_prerequisite.h Sun Mar 21 12:14:30 2010 @@ -2,19 +2,18 @@ /**************************************************************/ /*** this is included before any code produced by genc.py ***/ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* this must be defined before including other headers - in order to get a few extra functions like mremap() */ -#endif -/* XXX for now we always include Python.h even to produce stand-alone - * executables (which are *not* linked against CPython then), - * to get the convenient macro definitions - */ -#ifndef AVR -#include "Python.h" +#ifdef PYPY_STANDALONE +# include "src/commondefs.h" +#else +# include "Python.h" +#endif +#ifdef _WIN32 +# include /* needed, otherwise _lseeki64 truncates to 32-bits (??) */ +#endif +#ifndef AVR #include "thread.h" /* needs to be included early to define the struct RPyOpaque_ThreadLock */ #endif Modified: pypy/trunk/pypy/translator/c/src/main.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/main.h (original) +++ pypy/trunk/pypy/translator/c/src/main.h Sun Mar 21 12:14:30 2010 @@ -23,6 +23,12 @@ instrument_setup(); + if (sizeof(void*) != SIZEOF_LONG) { + errmsg = "only support platforms where sizeof(void*) == sizeof(long)," + " for now"; + goto error; + } + errmsg = RPython_StartupCode(); if (errmsg) goto error; Modified: pypy/trunk/pypy/translator/c/src/obmalloc.c ============================================================================== --- pypy/trunk/pypy/translator/c/src/obmalloc.c (original) +++ pypy/trunk/pypy/translator/c/src/obmalloc.c Sun Mar 21 12:14:30 2010 @@ -1,4 +1,3 @@ -#include "Python.h" #ifdef WITH_PYMALLOC Modified: pypy/trunk/pypy/translator/c/src/stack.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/stack.h (original) +++ pypy/trunk/pypy/translator/c/src/stack.h Sun Mar 21 12:14:30 2010 @@ -7,7 +7,8 @@ #endif /* This include must be done in any case to initialise - * the header dependencies early (thread -> winsock2, before windows.h) */ + * the header dependencies early (winsock2, before windows.h). + * It is needed to have RPyThreadStaticTLS, too. */ #include "thread.h" void LL_stack_unwind(void); Modified: pypy/trunk/pypy/translator/c/src/support.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/support.h (original) +++ pypy/trunk/pypy/translator/c/src/support.h Sun Mar 21 12:14:30 2010 @@ -2,6 +2,7 @@ /************************************************************/ /*** C header subsection: support functions ***/ +#include /*** misc ***/ Modified: pypy/trunk/pypy/translator/c/src/thread.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/thread.h (original) +++ pypy/trunk/pypy/translator/c/src/thread.h Sun Mar 21 12:14:30 2010 @@ -9,20 +9,13 @@ #include "thread_nt.h" #else -#include - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include /* _POSIX_THREADS */ -# endif -#endif - -#ifdef _POSIX_THREADS +/* We should check if unistd.h defines _POSIX_THREADS, but sometimes + it is not defined even though the system implements them as an + external library (e.g. gnu pth in pthread emulation). So we just + always go ahead and use them, assuming they are supported on all + platforms for which we care. If not, do some detecting again. +*/ #include "thread_pthread.h" -#endif #endif /* !_WIN32 */ Modified: pypy/trunk/pypy/translator/c/src/thread_pthread.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/thread_pthread.h (original) +++ pypy/trunk/pypy/translator/c/src/thread_pthread.h Sun Mar 21 12:14:30 2010 @@ -1,10 +1,24 @@ /* Posix threads interface (from CPython) */ +/* XXX needs to detect HAVE_BROKEN_POSIX_SEMAPHORES properly; currently + it is set only if _POSIX_SEMAPHORES == -1. Seems to be only for + SunOS/5.8 and AIX/5. +*/ + +#include /* for the _POSIX_xxx and _POSIX_THREAD_xxx defines */ +#include #include +#include #include #include +/* The following is hopefully equivalent to what CPython does + (which is trying to compile a snippet of code using it) */ +#ifdef PTHREAD_SCOPE_SYSTEM +# define PTHREAD_SYSTEM_SCHED_SUPPORTED +#endif + /* The POSIX spec says that implementations supporting the sem_* family of functions must indicate this by defining _POSIX_SEMAPHORES. */ @@ -114,11 +128,11 @@ volatile pthread_t threadid; /* Jump through some hoops for Alpha OSF/1 */ threadid = pthread_self(); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (long) threadid; -#else - return (long) *(long *) &threadid; -#endif + + if (sizeof(pthread_t) <= sizeof(long)) + return (long) threadid; + else + return (long) *(long *) &threadid; } static long _pypythread_stacksize = 0; @@ -171,11 +185,10 @@ pthread_detach(th); -#if SIZEOF_PTHREAD_T <= SIZEOF_LONG - return (long) th; -#else - return (long) *(long *) &th; -#endif + if (sizeof(pthread_t) <= sizeof(long)) + return (long) th; + else + return (long) *(long *) &th; } long RPyThreadGetStackSize(void) Modified: pypy/trunk/pypy/translator/c/test/test_dlltool.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_dlltool.py (original) +++ pypy/trunk/pypy/translator/c/test/test_dlltool.py Sun Mar 21 12:14:30 2010 @@ -2,6 +2,7 @@ from pypy.translator.c.dlltool import DLLDef from ctypes import CDLL import py +py.test.skip("fix this if needed") class TestDLLTool(object): def test_basic(self): Modified: pypy/trunk/pypy/translator/c/test/test_math.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_math.py (original) +++ pypy/trunk/pypy/translator/c/test/test_math.py Sun Mar 21 12:14:30 2010 @@ -1,6 +1,6 @@ import py, math from pypy.module.math.test import test_direct -from pypy.translator.c.test.test_genc import compile +from pypy.translator.c.test.test_standalone import StandaloneTests def get_test_case((fnname, args, expected)): @@ -25,18 +25,30 @@ testfnlist = [get_test_case(testcase) for testcase in test_direct.MathTests.TESTCASES] +reprlist = [repr(testcase) + for testcase in test_direct.MathTests.TESTCASES] -def fn(): +def fn(args): + err = False for i in range(len(testfnlist)): testfn = testfnlist[i] if not testfn(): - return i - return -42 # ok + print "error:", reprlist[i] + err = True + if not err: + print "all ok" + return 0 -def test_math(): - f = compile(fn, []) - res = f() - if res >= 0: - py.test.fail(repr(test_direct.MathTests.TESTCASES[res])) - else: - assert res == -42 + +class TestMath(StandaloneTests): + + def test_math(self, debug=True): + t, cbuilder = self.compile(fn, debug=debug) + data = cbuilder.cmdexec('') + if "error:" in data: + py.test.fail(data.strip()) + else: + assert "all ok" in data + + def test_math_nodebug(self): + self.test_math(debug=False) 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 Sun Mar 21 12:14:30 2010 @@ -205,16 +205,13 @@ #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: + if newpos == r4800000000: print "OK" else: print "BAD POS" @@ -674,7 +671,10 @@ def entry_point(argv): os.write(1, "hello world\n") error = ll_thread.set_stacksize(int(argv[1])) - assert error == 0 + if error != 0: + os.write(2, "set_stacksize(%d) returned %d\n" % ( + int(argv[1]), error)) + raise AssertionError # malloc a bit s1 = State(); s2 = State(); s3 = State() s1.x = 0x11111111; s2.x = 0x22222222; s3.x = 0x33333333 Modified: pypy/trunk/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/trunk/pypy/translator/tool/cbuild.py (original) +++ pypy/trunk/pypy/translator/tool/cbuild.py Sun Mar 21 12:14:30 2010 @@ -225,6 +225,7 @@ return ExternalCompilationInfo(**attrs) def write_c_header(self, fileobj): + print >> fileobj, STANDARD_DEFINES for piece in self.pre_include_bits: print >> fileobj, piece for path in self.includes: @@ -254,8 +255,6 @@ f = filename.open("w") if being_main: f.write("#define PYPY_NOT_MAIN_FILE\n") - if sys.platform == 'win32': - f.write("#define WIN32_LEAN_AND_MEAN\n") self.write_c_header(f) source = str(source) f.write(source) @@ -292,3 +291,28 @@ d['separate_module_files'] = () d['separate_module_sources'] = () return ExternalCompilationInfo(**d) + + +# ____________________________________________________________ +# +# This is extracted from pyconfig.h from CPython. It sets the macros +# that affect the features we get from system include files. + +STANDARD_DEFINES = ''' +/* Define on Darwin to activate all library features */ +#define _DARWIN_C_SOURCE 1 +/* This must be set to 64 on some systems to enable large file support. */ +#define _FILE_OFFSET_BITS 64 +/* Define on Linux to activate all library features */ +#define _GNU_SOURCE 1 +/* This must be defined on some systems to enable large file support. */ +#define _LARGEFILE_SOURCE 1 +/* Define on NetBSD to activate all library features */ +#define _NETBSD_SOURCE 1 +/* Define to activate features from IEEE Stds 1003.1-2001 */ +#define _POSIX_C_SOURCE 200112L +/* Define on FreeBSD to activate all library features */ +#define __BSD_VISIBLE 1 +/* Windows: winsock/winsock2 mess */ +#define WIN32_LEAN_AND_MEAN +''' From arigo at codespeak.net Sun Mar 21 12:14:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 12:14:47 +0100 (CET) Subject: [pypy-svn] r72489 - pypy/branch/kill-python-h Message-ID: <20100321111447.8F2BD282B90@codespeak.net> Author: arigo Date: Sun Mar 21 12:14:46 2010 New Revision: 72489 Removed: pypy/branch/kill-python-h/ Log: Branch merged. From arigo at codespeak.net Sun Mar 21 12:20:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 12:20:06 +0100 (CET) Subject: [pypy-svn] r72490 - in pypy/trunk/pypy: rpython/lltypesystem rpython/memory/gc rpython/memory/gctransform translator/c translator/c/src Message-ID: <20100321112006.3AD23282B90@codespeak.net> Author: arigo Date: Sun Mar 21 12:20:04 2010 New Revision: 72490 Modified: pypy/trunk/pypy/rpython/lltypesystem/llgroup.py pypy/trunk/pypy/rpython/memory/gc/markcompact.py pypy/trunk/pypy/rpython/memory/gc/marksweep.py pypy/trunk/pypy/rpython/memory/gc/semispace.py pypy/trunk/pypy/rpython/memory/gctransform/framework.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/primitive.py pypy/trunk/pypy/translator/c/src/llgroup.h Log: Change the CombinedSymbolics on 64-bit machines: they are now two 32-bit halves, instead of a USHORT and the rest. This allows a simpler and (likely) faster implementation of llgroup.h, where instead of this complex 16-bit number we just store the pointer in the lower 32 bits. This should work everywhere because the pointers are always to static data, and so they probably always fit in a 32-bit field. (This is checked, of course.) Modified: pypy/trunk/pypy/rpython/lltypesystem/llgroup.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llgroup.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llgroup.py Sun Mar 21 12:20:04 2010 @@ -1,13 +1,19 @@ import weakref from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rlib.rarithmetic import LONG_BIT class GroupType(lltype.ContainerType): """A 'group' that stores static structs together in memory. - The point is that they can be referenced by a GroupMemberOffset - which only takes 2 bytes (a USHORT), so the total size of a group - is limited to 18 or 19 bits (= the 16 bits in a USHORT, plus 2 or - 3 bits at the end that are zero and so don't need to be stored). + + On 32-bit platforms, the point is that they can be referenced by a + GroupMemberOffset which only takes 2 bytes (a USHORT), so the total + size of a group is limited to 18 (= the 16 bits in a USHORT, plus 2 + bits at the end that are zero and so don't need to be stored). + + On 64-bit platforms, we check that the address they end up at is + within the first 32 bits, so that we can store that address in half + a long (i.e. in a UINT). """ _gckind = 'raw' @@ -43,16 +49,24 @@ _membership = weakref.WeakValueDictionary() +if LONG_BIT == 32: + HALFWORD = rffi.USHORT + r_halfword = rffi.r_ushort +else: + HALFWORD = rffi.UINT + r_halfword = rffi.r_uint + + class GroupMemberOffset(llmemory.Symbolic): - """The offset of a struct inside a group, stored compactly in a USHORT. - Can only be used by the lloperation 'get_group_member'. + """The offset of a struct inside a group, stored compactly in a HALFWORD + (a USHORT or UINT). Can only be used by the lloperation 'get_group_member'. """ def annotation(self): from pypy.annotation import model - return model.SomeInteger(knowntype=rffi.r_ushort) + return model.SomeInteger(knowntype=r_halfword) def lltype(self): - return rffi.USHORT + return HALFWORD def __init__(self, grp, memberindex): assert lltype.typeOf(grp) == Group @@ -76,11 +90,15 @@ class CombinedSymbolic(llmemory.Symbolic): - """A general-purpose Signed symbolic that combines a USHORT and the - rest of the word (typically flags). Only supports extracting the USHORT + """A general-purpose Signed symbolic that combines an unsigned half-word + (USHORT on 32-bit platforms, UINT on 64-bit platforms) and the rest + of the word (typically flags). Only supports extracting the half-word with 'llop.extract_ushort', and extracting the rest of the word with - '&~0xFFFF' or with a direct masking like '&0x10000'. + '&~0xFFFF' or with a direct masking like '&0x10000' (resp. on 64-bit + platform, with '&~0xFFFFFFFF' or '&0x100000000'). """ + MASK = (1<<(LONG_BIT//2))-1 # 0xFFFF or 0xFFFFFFFF + def annotation(self): from pypy.annotation import model return model.SomeInteger() @@ -89,7 +107,7 @@ return lltype.Signed def __init__(self, lowpart, rest): - assert (rest & 0xFFFF) == 0 + assert (rest & CombinedSymbolic.MASK) == 0 self.lowpart = lowpart self.rest = rest @@ -97,22 +115,22 @@ return '' % (self.lowpart, self.rest) def __and__(self, other): - if (other & 0xFFFF) == 0: + if (other & CombinedSymbolic.MASK) == 0: return self.rest & other - if (other & 0xFFFF) == 0xFFFF: + if (other & CombinedSymbolic.MASK) == CombinedSymbolic.MASK: return CombinedSymbolic(self.lowpart, self.rest & other) raise Exception("other=0x%x" % other) def __or__(self, other): - assert (other & 0xFFFF) == 0 + assert (other & CombinedSymbolic.MASK) == 0 return CombinedSymbolic(self.lowpart, self.rest | other) def __add__(self, other): - assert (other & 0xFFFF) == 0 + assert (other & CombinedSymbolic.MASK) == 0 return CombinedSymbolic(self.lowpart, self.rest + other) def __sub__(self, other): - assert (other & 0xFFFF) == 0 + assert (other & CombinedSymbolic.MASK) == 0 return CombinedSymbolic(self.lowpart, self.rest - other) def __eq__(self, other): 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 Sun Mar 21 12:20:04 2010 @@ -66,7 +66,7 @@ # XXX adjust GC_CLEARANCE = 32*1024 -TID_TYPE = rffi.USHORT +TID_TYPE = llgroup.HALFWORD BYTES_PER_TID = rffi.sizeof(TID_TYPE) @@ -354,7 +354,7 @@ def get_type_id(self, addr): tid = self.header(addr).tid - return llop.extract_ushort(rffi.USHORT, tid) + return llop.extract_ushort(llgroup.HALFWORD, tid) def mark_roots_recursively(self): self.root_walker.walk_roots( Modified: pypy/trunk/pypy/rpython/memory/gc/marksweep.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/marksweep.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/marksweep.py Sun Mar 21 12:20:04 2010 @@ -4,7 +4,7 @@ from pypy.rpython.memory.support import DEFAULT_CHUNK_SIZE from pypy.rpython.memory.support import get_address_stack from pypy.rpython.memory.gcheader import GCHeaderBuilder -from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, llgroup from pypy.rlib.objectmodel import free_non_gc_object from pypy.rpython.lltypesystem.lloperation import llop from pypy.rlib.rarithmetic import ovfcheck @@ -29,7 +29,7 @@ HDRPTR = lltype.Ptr(HDR) # need to maintain a linked list of malloced objects, since we used the # systems allocator and can't walk the heap - HDR.become(lltype.Struct('header', ('typeid16', rffi.USHORT), + HDR.become(lltype.Struct('header', ('typeid16', llgroup.HALFWORD), ('mark', lltype.Bool), ('flags', lltype.Char), ('next', HDRPTR))) Modified: pypy/trunk/pypy/rpython/memory/gc/semispace.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gc/semispace.py (original) +++ pypy/trunk/pypy/rpython/memory/gc/semispace.py Sun Mar 21 12:20:04 2010 @@ -4,18 +4,18 @@ 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 import lltype, llmemory, llarena, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi, llgroup from pypy.rlib.objectmodel import free_non_gc_object from pypy.rlib.debug import ll_assert, have_debug_prints from pypy.rlib.debug import debug_print, debug_start, debug_stop from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.rarithmetic import ovfcheck +from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT from pypy.rpython.memory.gc.base import MovingGCBase, ARRAY_TYPEID_MAP,\ TYPEID_MAP import sys, os -first_gcflag = 1 << 16 +first_gcflag = 1 << (LONG_BIT//2) 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 @@ -458,7 +458,7 @@ # 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 llop.extract_ushort(rffi.USHORT, tid) + return llop.extract_ushort(llgroup.HALFWORD, tid) def init_gc_object(self, addr, typeid16, flags=0): hdr = llmemory.cast_adr_to_ptr(addr, lltype.Ptr(self.HDR)) Modified: pypy/trunk/pypy/rpython/memory/gctransform/framework.py ============================================================================== --- pypy/trunk/pypy/rpython/memory/gctransform/framework.py (original) +++ pypy/trunk/pypy/rpython/memory/gctransform/framework.py Sun Mar 21 12:20:04 2010 @@ -1,7 +1,7 @@ from pypy.rpython.memory.gctransform.transform import GCTransformer from pypy.rpython.memory.gctransform.support import find_gc_ptrs_in_type, \ get_rtti, ll_call_destructor, type_contains_pyobjs, var_ispyobj -from pypy.rpython.lltypesystem import lltype, llmemory, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, rffi, llgroup from pypy.rpython import rmodel from pypy.rpython.memory import gctypelayout from pypy.rpython.memory.gc import marksweep @@ -22,7 +22,7 @@ import sys, types -TYPE_ID = rffi.USHORT +TYPE_ID = llgroup.HALFWORD class CollectAnalyzer(graphanalyze.BoolGraphAnalyzer): @@ -302,7 +302,7 @@ minimal_transform=False) self.get_member_index_ptr = getfn( GCClass.get_member_index.im_func, - [s_gc, annmodel.SomeInteger(knowntype=rffi.r_ushort)], + [s_gc, annmodel.SomeInteger(knowntype=llgroup.r_halfword)], annmodel.SomeInteger()) if hasattr(GCClass, 'writebarrier_before_copy'): Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Sun Mar 21 12:20:04 2010 @@ -989,13 +989,18 @@ forward_cdecl(ctype, self.name, self.db.standalone, self.is_thread_local())) yield '#include "src/llgroup.h"' - yield 'PYPY_GROUP_CHECK_SIZE(%s);' % self.name for i, member in enumerate(self.obj.members): structnode = self.db.getcontainernode(member) yield '#define %s %s.member%d' % (structnode.name, self.name, i) yield '' + def startupcode(self): + count = len(self.obj.members) + if count == 0: + return [] + return ['PYPY_GROUP_CHECK_SIZE(%s, member%d);' % (self.name, count-1)] + def initializationexpr(self): self._fix_members() lines = ['{'] Modified: pypy/trunk/pypy/translator/c/primitive.py ============================================================================== --- pypy/trunk/pypy/translator/c/primitive.py (original) +++ pypy/trunk/pypy/translator/c/primitive.py Sun Mar 21 12:20:04 2010 @@ -58,7 +58,9 @@ elif isinstance(value, ComputedIntSymbolic): value = value.compute_fn() elif isinstance(value, llgroup.CombinedSymbolic): - return '(%s|%dL)' % (name_ushort(value.lowpart, db), value.rest) + name = name_small_integer(value.lowpart, db) + assert (value.rest & value.MASK) == 0 + return '(%s+%dL)' % (name, value.rest) else: raise Exception("unimplemented symbolic %r"%value) if value is None: @@ -139,12 +141,14 @@ else: return 'NULL' -def name_ushort(value, db): +def name_small_integer(value, db): + """Works for integers of size at most INT or UINT.""" if isinstance(value, Symbolic): if isinstance(value, llgroup.GroupMemberOffset): groupnode = db.getcontainernode(value.grpptr._as_obj()) - return 'GROUP_MEMBER_OFFSET(%s, member%s)' % ( + return 'GROUP_MEMBER_OFFSET(%s, %s, member%s)' % ( cdecl(groupnode.implementationtypename, ''), + groupnode.name, value.index, ) else: @@ -166,7 +170,6 @@ Void: name_void, Address: name_address, GCREF: name_gcref, - rffi.USHORT: name_ushort, } PrimitiveType = { @@ -182,27 +185,25 @@ Void: 'void @', Address: 'void* @', GCREF: 'void* @', - rffi.USHORT: 'unsigned short @', } -def define_c_primitive(ll_type, c_name): +def define_c_primitive(ll_type, c_name, suffix=''): if ll_type in PrimitiveName: return - if ll_type._cast(-1) > 0: - name_str = '((%s) %%dULL)' % c_name + if suffix == '': + PrimitiveName[ll_type] = name_small_integer else: - name_str = '((%s) %%dLL)' % c_name - PrimitiveName[ll_type] = lambda value, db: name_str % value + name_str = '((%s) %%d%s)' % (c_name, suffix) + PrimitiveName[ll_type] = lambda value, db: name_str % value PrimitiveType[ll_type] = '%s @'% c_name - -for ll_type, c_name in [(rffi.SIGNEDCHAR, 'signed char'), - (rffi.UCHAR, 'unsigned char'), - (rffi.SHORT, 'short'), - #(rffi.USHORT, 'unsigned short'), - (rffi.INT, 'int'), - (rffi.UINT, 'unsigned int'), - (rffi.LONG, 'long'), - (rffi.ULONG, 'unsigned long'), - (rffi.LONGLONG, 'long long'), - (rffi.ULONGLONG, 'unsigned long long')]: - define_c_primitive(ll_type, c_name) + +define_c_primitive(rffi.SIGNEDCHAR, 'signed char') +define_c_primitive(rffi.UCHAR, 'unsigned char') +define_c_primitive(rffi.SHORT, 'short') +define_c_primitive(rffi.USHORT, 'unsigned short') +define_c_primitive(rffi.INT, 'int') +define_c_primitive(rffi.UINT, 'unsigned int') +define_c_primitive(rffi.LONG, 'long', 'L') +define_c_primitive(rffi.ULONG, 'unsigned long', 'UL') +define_c_primitive(rffi.LONGLONG, 'long long', 'LL') +define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL') Modified: pypy/trunk/pypy/translator/c/src/llgroup.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/llgroup.h (original) +++ pypy/trunk/pypy/translator/c/src/llgroup.h Sun Mar 21 12:20:04 2010 @@ -1,29 +1,63 @@ #ifndef _PYPY_LL_GROUP_H_ #define _PYPY_LL_GROUP_H_ -#define GROUP_MEMBER_OFFSET(grouptype, membername) \ - ((unsigned short)(((int)&((grouptype*)NULL)->membername) / sizeof(long))) +/* Support code for CombinedSymbolics */ + + +#if PYPY_LONG_BIT == 32 /************************************/ +/* On 32-bit platforms, a CombinedSymbolic is two USHORTs, and the + lower one stores the offset inside the group, divided by 4. The + limitation is to have at most 256KB of data in the whole group. */ + +#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ + ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 4)) + +#define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ + (((char*)groupptr) + ((long)compactoffset)*4) + +#define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ + ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*4) + +#define OP_IS_GROUP_MEMBER_NONZERO(compactoffset, r) \ + r = (compactoffset != 0) + +#define OP_EXTRACT_USHORT(value, r) r = (unsigned short)value +#define OP_COMBINE_USHORT(ushort, rest, r) r = ((long)ushort) | rest + +/* A macro to check at run-time if sizeof(group) is too large. */ +#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ + if (sizeof(groupname) > 65536*4) \ + error = "group " #groupname " is more than 256KB of data" + + +#else /******************************************************/ +/* On 64-bit platforms, a CombinedSymbolic is two UINTs, and the lower + one stores a real pointer to the group memeber. The limitation is + that this pointer must fit inside 32-bit, i.e. the whole group must + be located in the first 32 bits of address space. */ + +#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ + ((long)(&groupname.membername)) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ - (((char*)groupptr) + ((long)compactoffset)*sizeof(long)) + ((long)compactoffset) #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ - ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*sizeof(long)) + ((long)compactoffset + skipoffset) #define OP_IS_GROUP_MEMBER_NONZERO(compactoffset, r) \ r = (compactoffset != 0) -#define OP_EXTRACT_USHORT(value, r) \ - r = (unsigned short)value +#define OP_EXTRACT_USHORT(value, r) r = (unsigned int)value +#define OP_COMBINE_USHORT(ushort, rest, r) r = ((long)ushort) | rest -#define OP_COMBINE_USHORT(ushort, rest, r) \ - r = ((long)ushort) | rest; +/* A macro to check at run-time if the group is below the 32-bit limit. */ +#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ + if ((unsigned long)(&groupname.lastname) > 0xFFFFFFFF) \ + error = "group " #groupname " is not located in the " \ + "initial 32 bits of address space" -/* A macro to crash at compile-time if sizeof(group) is too large. - Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ -#define PYPY_GROUP_CHECK_SIZE(groupname) \ - typedef char group_##groupname##_is_too_large[2*(sizeof(groupname) \ - <= 65536 * sizeof(long))-1] +#endif /*****************************************************/ #endif /* _PYPY_LL_GROUP_H_ */ From arigo at codespeak.net Sun Mar 21 15:03:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 15:03:20 +0100 (CET) Subject: [pypy-svn] r72491 - pypy/trunk/pypy/config Message-ID: <20100321140320.38BF8282B90@codespeak.net> Author: arigo Date: Sun Mar 21 15:03:18 2010 New Revision: 72491 Modified: pypy/trunk/pypy/config/translationoption.py Log: Make 'gcremovetypeptr' True by default on 64-bit platforms. Indeed, it seems to improve speed as well (~+5%). Modified: pypy/trunk/pypy/config/translationoption.py ============================================================================== --- pypy/trunk/pypy/config/translationoption.py (original) +++ pypy/trunk/pypy/config/translationoption.py Sun Mar 21 15:03:18 2010 @@ -1,5 +1,5 @@ import autopath -import py, os +import py, os, sys from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config from pypy.config.config import ConfigError @@ -11,6 +11,8 @@ DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4 DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0 +IS_64_BITS = sys.maxint > 2147483647 + PLATFORMS = [ 'maemo', 'host', @@ -73,7 +75,7 @@ ("translation.gcremovetypeptr", False)], }), BoolOption("gcremovetypeptr", "Remove the typeptr from every object", - default=False, cmdline="--gcremovetypeptr"), + default=IS_64_BITS, cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "asmgcc"], From arigo at codespeak.net Sun Mar 21 15:44:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 15:44:59 +0100 (CET) Subject: [pypy-svn] r72492 - pypy/trunk/pypy/config Message-ID: <20100321144459.1A987282B90@codespeak.net> Author: arigo Date: Sun Mar 21 15:44:57 2010 New Revision: 72492 Modified: pypy/trunk/pypy/config/translationoption.py Log: Sorry, my mistake. The +5% is caused only by the previous check-in, not be actually enabling gcremovetypeptr. Doing so crashes pypy-c so far on 64-bits. Modified: pypy/trunk/pypy/config/translationoption.py ============================================================================== --- pypy/trunk/pypy/config/translationoption.py (original) +++ pypy/trunk/pypy/config/translationoption.py Sun Mar 21 15:44:57 2010 @@ -1,5 +1,5 @@ import autopath -import py, os, sys +import py, os from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config from pypy.config.config import ConfigError @@ -11,8 +11,6 @@ DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4 DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0 -IS_64_BITS = sys.maxint > 2147483647 - PLATFORMS = [ 'maemo', 'host', @@ -75,7 +73,7 @@ ("translation.gcremovetypeptr", False)], }), BoolOption("gcremovetypeptr", "Remove the typeptr from every object", - default=IS_64_BITS, cmdline="--gcremovetypeptr"), + default=False, cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "asmgcc"], From arigo at codespeak.net Sun Mar 21 16:22:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 16:22:26 +0100 (CET) Subject: [pypy-svn] r72493 - in pypy/trunk/pypy: rpython/lltypesystem translator/c translator/c/src translator/c/test Message-ID: <20100321152226.CD60A282B90@codespeak.net> Author: arigo Date: Sun Mar 21 16:22:25 2010 New Revision: 72493 Modified: pypy/trunk/pypy/rpython/lltypesystem/llarena.py pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/c/gc.py pypy/trunk/pypy/translator/c/src/llgroup.h pypy/trunk/pypy/translator/c/test/test_newgc.py Log: 64bit: Fix some tests, avoid a warning, fix a last forgotten "unsigned short" in gc.py. Modified: pypy/trunk/pypy/rpython/lltypesystem/llarena.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llarena.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llarena.py Sun Mar 21 16:22:25 2010 @@ -357,12 +357,15 @@ # usage hint but a real command. It guarantees that after MADV_DONTNEED # the pages are cleared again. from pypy.rpython.tool import rffi_platform + from pypy.translator.tool.cbuild import ExternalCompilationInfo + _eci = ExternalCompilationInfo(includes=['sys/mman.h']) MADV_DONTNEED = rffi_platform.getconstantinteger('MADV_DONTNEED', '#include ') linux_madvise = rffi.llexternal('madvise', [llmemory.Address, rffi.SIZE_T, rffi.INT], rffi.INT, - sandboxsafe=True, _nowrapper=True) + sandboxsafe=True, _nowrapper=True, + compilation_info=_eci) linux_getpagesize = rffi.llexternal('getpagesize', [], rffi.INT, sandboxsafe=True, _nowrapper=True) Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Sun Mar 21 16:22:25 2010 @@ -209,6 +209,7 @@ def cfunction_body(self): graph = self.graph + yield 'goto block0;' # to avoid a warning "this label is not used" # generate the body of each block for block in graph.iterblocks(): Modified: pypy/trunk/pypy/translator/c/gc.py ============================================================================== --- pypy/trunk/pypy/translator/c/gc.py (original) +++ pypy/trunk/pypy/translator/c/gc.py Sun Mar 21 16:22:25 2010 @@ -364,7 +364,7 @@ typename = funcgen.db.gettype(op.result.concretetype) fieldname = c_vtableinfo.value[2] return ( - '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (unsigned short)%s->_%s, %s);' + '%s = (%s)_OP_GET_NEXT_GROUP_MEMBER(%s, (pypy_halfword_t)%s->_%s, %s);' % (funcgen.expr(op.result), cdecl(typename, ''), funcgen.expr(c_grpptr), Modified: pypy/trunk/pypy/translator/c/src/llgroup.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/llgroup.h (original) +++ pypy/trunk/pypy/translator/c/src/llgroup.h Sun Mar 21 16:22:25 2010 @@ -9,6 +9,8 @@ lower one stores the offset inside the group, divided by 4. The limitation is to have at most 256KB of data in the whole group. */ +typedef unsigned short pypy_halfword_t; + #define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 4)) @@ -17,13 +19,6 @@ #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*4) - -#define OP_IS_GROUP_MEMBER_NONZERO(compactoffset, r) \ - r = (compactoffset != 0) - -#define OP_EXTRACT_USHORT(value, r) r = (unsigned short)value -#define OP_COMBINE_USHORT(ushort, rest, r) r = ((long)ushort) | rest - /* A macro to check at run-time if sizeof(group) is too large. */ #define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ if (sizeof(groupname) > 65536*4) \ @@ -36,6 +31,8 @@ that this pointer must fit inside 32-bit, i.e. the whole group must be located in the first 32 bits of address space. */ +typedef unsigned int pypy_halfword_t; + #define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ ((long)(&groupname.membername)) @@ -45,12 +42,6 @@ #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ ((long)compactoffset + skipoffset) -#define OP_IS_GROUP_MEMBER_NONZERO(compactoffset, r) \ - r = (compactoffset != 0) - -#define OP_EXTRACT_USHORT(value, r) r = (unsigned int)value -#define OP_COMBINE_USHORT(ushort, rest, r) r = ((long)ushort) | rest - /* A macro to check at run-time if the group is below the 32-bit limit. */ #define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ if ((unsigned long)(&groupname.lastname) > 0xFFFFFFFF) \ @@ -60,4 +51,11 @@ #endif /*****************************************************/ + +#define OP_IS_GROUP_MEMBER_NONZERO(compactoffset, r) \ + r = (compactoffset != 0) + +#define OP_EXTRACT_USHORT(value, r) r = (pypy_halfword_t)value +#define OP_COMBINE_USHORT(ushort, rest, r) r = ((long)ushort) | rest + #endif /* _PYPY_LL_GROUP_H_ */ Modified: pypy/trunk/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_newgc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_newgc.py Sun Mar 21 16:22:25 2010 @@ -621,7 +621,7 @@ CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint from pypy.rpython.lltypesystem import rffi, ll2ctypes import gc - slong = cast_type_to_ffitype(rffi.LONG) + ffi_size_t = cast_type_to_ffitype(rffi.SIZE_T) from pypy.rlib.libffi import get_libc_name @@ -629,32 +629,32 @@ 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] + a1 = rffi.cast(rffi.LONGP, p_a1)[0] + a2 = rffi.cast(rffi.LONGP, p_a2)[0] res = rffi.cast(rffi.INTP, ll_res) if a1 > a2: - res[0] = 1 + res[0] = rffi.cast(rffi.INT, 1) else: - res[0] = -1 + res[0] = rffi.cast(rffi.INT, -1) def f(): libc = CDLL(get_libc_name()) - qsort = libc.getpointer('qsort', [ffi_type_pointer, slong, - slong, ffi_type_pointer], - ffi_type_void) + qsort = libc.getpointer('qsort', [ffi_type_pointer, ffi_size_t, + ffi_size_t, ffi_type_pointer], + ffi_type_void) ptr = CallbackFuncPtr([ffi_type_pointer, ffi_type_pointer], ffi_type_sint, callback) - TP = rffi.CArray(rffi.INT) + TP = rffi.CArray(rffi.LONG) 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.SIZE_T, rffi.sizeof(rffi.LONG))) + qsort.push_arg(rffi.cast(rffi.SIZE_T, 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] @@ -904,7 +904,7 @@ def f(): from pypy.rpython.lltypesystem import lltype, rffi alist = [A() for i in range(50000)] - idarray = lltype.malloc(rffi.INTP.TO, len(alist), flavor='raw') + idarray = lltype.malloc(rffi.LONGP.TO, len(alist), flavor='raw') # Compute the id of all elements of the list. The goal is # to not allocate memory, so that if the GC needs memory to # remember the ids, it will trigger some collections itself From xoraxax at codespeak.net Sun Mar 21 16:53:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 16:53:03 +0100 (CET) Subject: [pypy-svn] r72494 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100321155303.25531282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 16:53:01 2010 New Revision: 72494 Modified: pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/test/test_typeobject.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: Whack more ... Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sun Mar 21 16:53:01 2010 @@ -11,10 +11,9 @@ class W_PyCFunctionObject(Wrappable): - def __init__(self, ml, w_self, w_modname): + def __init__(self, ml, w_self): self.ml = ml self.w_self = w_self - self.w_modname = w_modname @unwrap_spec(ObjSpace, W_Root, Arguments) def cfunction_descr_call(space, w_self, __args__): @@ -45,5 +44,5 @@ __call__ = interp2app(cfunction_descr_call), ) -def PyCFunction_NewEx(space, ml, w_self, w_modname): - return space.wrap(W_PyCFunctionObject(ml, w_self, w_modname)) +def PyCFunction_NewEx(space, ml, w_self): + return space.wrap(W_PyCFunctionObject(ml, w_self)) Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 16:53:01 2010 @@ -25,7 +25,15 @@ def Py_InitModule(space, name, methods): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) + dict_w = convert_method_defs(space, methods) + for w_key, w_value in dict_w.items(): + space.setattr(w_mod, w_key, w_value) + return w_mod + + +def convert_method_defs(space, methods): methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) + dict_w = {} if methods: i = 0 while True: @@ -34,12 +42,11 @@ methodname = rffi.charp2str(method.c_ml_name) flags = method.c_ml_flags - w_function = PyCFunction_NewEx(space, method, None, modname) - space.setattr(w_mod, - space.wrap(methodname), - w_function) + w_function = PyCFunction_NewEx(space, method, None) + dict_w[space.wrap(methodname)] = w_function i = i + 1 - return w_mod + return dict_w + @cpython_api([PyObject], rffi.INT) def PyModule_Check(space, w_obj): Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sun Mar 21 16:53:01 2010 @@ -1,17 +1,16 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref -from pypy.module.cpyext.typeobject import PyTypeObjectPtr +from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject def get_cls_for_type_object(space, w_type): - if space.is_w(w_type, space.w_object): - return W_ObjectObject - assert False, "Please add more cases!" + if isinstance(w_type, W_PyCTypeObject): + return space.allocate_instance(W_PyCObject, space.gettypeobject(W_PyCObject.typedef)) + assert False, "Please add more cases in get_cls_for_type_object!" @cpython_api([PyObject], PyObject) def _PyObject_New(space, w_type): - cls = get_cls_for_type_object(space, w_type) - return space.allocate_instance(cls, w_type) + return get_cls_for_type_object(space, w_type) @cpython_api([rffi.VOIDP_real], lltype.Void) def PyObject_Del(space, w_obj): Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 16:53:01 2010 @@ -10,4 +10,9 @@ module = self.import_module(name='foo') assert 'foo' in sys.modules print module.fooType + obj = module.new() + print "Obj has type", type(obj) + assert type(obj) is module.fooType + print "type of obj has type", type(type(obj)) + obj2 = obj.copy() assert module.new().name == "Foo Example" Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 16:53:01 2010 @@ -5,11 +5,13 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable +from pypy.objspace.std.typeobject import W_TypeObject +from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject,\ PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module -from pypy.module.cpyext.modsupport import PyMethodDef +from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State PyTypeObject = lltype.ForwardReference() @@ -122,7 +124,7 @@ ("tp_dict", PyObject), ("tp_descr_get", descrgetfunc), ("tp_descr_set", descrsetfunc), - ("tp_dictoffset", Py_ssize_t), + ("tp_dictoffset", Py_ssize_t), # can be ignored in PyPy ("tp_init", initproc), ("tp_alloc", allocfunc), ("tp_new", newfunc), @@ -140,10 +142,10 @@ PyTypeObjectFields, PyTypeObject) -class W_PyCTypeObject(Wrappable): +class W_PyCTypeObject(W_TypeObject): pass -class W_PyCObject(Wrappable): +class W_PyCObject(W_ObjectObject): pass @unwrap_spec(ObjSpace, W_Root, W_Root) @@ -153,11 +155,20 @@ def allocate_type_obj(space, w_obj): - py_obj = lltype.malloc(PyTypeObject, None, flavor="raw") - return py_obj + pto = lltype.malloc(PyTypeObject, None, flavor="raw") + # XXX fill slots in pto + return pto def create_type_object(space, pto): - return space.gettypeobject(W_PyCTypeObject) + bases_w = [] + dict_w = convert_method_defs(space, pto.c_tp_methods) + + w_type = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) + W_TypeObject.__init__(w_type, space, rffi.charp2str(pto.c_tp_name), + bases_w or [space.w_object], dict_w) + w_type.ready() + return w_type + @cpython_api([PyTypeObjectPtr], rffi.INT) def PyPyType_Register(space, pto): @@ -171,9 +182,9 @@ W_PyCObject.typedef = TypeDef( 'C_object', - __getattr__ = interp2app(cobject_descr_getattr), + #__getattrbute__ = interp2app(cobject_descr_getattribute), ) W_PyCTypeObject.typedef = TypeDef( - 'C_type' + 'C_type', W_TypeObject.typedef ) From arigo at codespeak.net Sun Mar 21 16:57:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 21 Mar 2010 16:57:41 +0100 (CET) Subject: [pypy-svn] r72495 - pypy/trunk/pypy/config Message-ID: <20100321155741.77F2E282B90@codespeak.net> Author: arigo Date: Sun Mar 21 16:57:39 2010 New Revision: 72495 Modified: pypy/trunk/pypy/config/translationoption.py Log: Set (again) gcremovetypeptr as default for 64-bit translations. It gives a pypy-c that is faster (+10%), consumes less memory of course, and is smaller. Modified: pypy/trunk/pypy/config/translationoption.py ============================================================================== --- pypy/trunk/pypy/config/translationoption.py (original) +++ pypy/trunk/pypy/config/translationoption.py Sun Mar 21 16:57:39 2010 @@ -1,5 +1,5 @@ import autopath -import py, os +import py, os, sys from pypy.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from pypy.config.config import ChoiceOption, StrOption, to_optparse, Config from pypy.config.config import ConfigError @@ -11,6 +11,8 @@ DEFL_CLEVER_MALLOC_REMOVAL_INLINE_THRESHOLD = 32.4 DEFL_LOW_INLINE_THRESHOLD = DEFL_INLINE_THRESHOLD / 2.0 +IS_64_BITS = sys.maxint > 2147483647 + PLATFORMS = [ 'maemo', 'host', @@ -73,7 +75,7 @@ ("translation.gcremovetypeptr", False)], }), BoolOption("gcremovetypeptr", "Remove the typeptr from every object", - default=False, cmdline="--gcremovetypeptr"), + default=IS_64_BITS, cmdline="--gcremovetypeptr"), ChoiceOption("gcrootfinder", "Strategy for finding GC Roots (framework GCs only)", ["n/a", "shadowstack", "asmgcc"], From xoraxax at codespeak.net Sun Mar 21 17:24:18 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 17:24:18 +0100 (CET) Subject: [pypy-svn] r72496 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100321162418.6AD40282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 17:24:16 2010 New Revision: 72496 Modified: pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Log: Fix wrapping bug. Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 17:24:16 2010 @@ -26,8 +26,8 @@ modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) dict_w = convert_method_defs(space, methods) - for w_key, w_value in dict_w.items(): - space.setattr(w_mod, w_key, w_value) + for key, w_value in dict_w.items(): + space.setattr(w_mod, space.wrap(key), w_value) return w_mod @@ -43,7 +43,7 @@ methodname = rffi.charp2str(method.c_ml_name) flags = method.c_ml_flags w_function = PyCFunction_NewEx(space, method, None) - dict_w[space.wrap(methodname)] = w_function + dict_w[methodname] = w_function i = i + 1 return dict_w Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 17:24:16 2010 @@ -9,7 +9,7 @@ import sys module = self.import_module(name='foo') assert 'foo' in sys.modules - print module.fooType + assert "copy" in dir(module.fooType) obj = module.new() print "Obj has type", type(obj) assert type(obj) is module.fooType From xoraxax at codespeak.net Sun Mar 21 17:24:44 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 17:24:44 +0100 (CET) Subject: [pypy-svn] r72497 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100321162444.F0786282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 17:24:43 2010 New Revision: 72497 Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Log: Fix wrapping bug. Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 17:24:43 2010 @@ -5,11 +5,12 @@ class AppTestTypeObject(AppTestCpythonExtensionBase): def test_typeobject(self): - skip("In progress") + #skip("In progress") import sys module = self.import_module(name='foo') assert 'foo' in sys.modules assert "copy" in dir(module.fooType) + print module.fooType.copy obj = module.new() print "Obj has type", type(obj) assert type(obj) is module.fooType From xoraxax at codespeak.net Sun Mar 21 17:26:16 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 17:26:16 +0100 (CET) Subject: [pypy-svn] r72498 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100321162616.C6225282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 17:26:15 2010 New Revision: 72498 Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Log: Add skip again. Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 17:26:15 2010 @@ -5,7 +5,7 @@ class AppTestTypeObject(AppTestCpythonExtensionBase): def test_typeobject(self): - #skip("In progress") + skip("In progress") import sys module = self.import_module(name='foo') assert 'foo' in sys.modules From xoraxax at codespeak.net Sun Mar 21 17:44:16 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 17:44:16 +0100 (CET) Subject: [pypy-svn] r72499 - pypy/trunk/pypy/module/cpyext Message-ID: <20100321164416.EB151282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 17:44:15 2010 New Revision: 72499 Modified: pypy/trunk/pypy/module/cpyext/object.py Log: Use w_type here, does not work, though. Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sun Mar 21 17:44:15 2010 @@ -5,7 +5,7 @@ def get_cls_for_type_object(space, w_type): if isinstance(w_type, W_PyCTypeObject): - return space.allocate_instance(W_PyCObject, space.gettypeobject(W_PyCObject.typedef)) + return space.allocate_instance(W_PyCObject, w_type) assert False, "Please add more cases in get_cls_for_type_object!" @cpython_api([PyObject], PyObject) From afa at codespeak.net Sun Mar 21 18:04:11 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 21 Mar 2010 18:04:11 +0100 (CET) Subject: [pypy-svn] r72500 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100321170411.88B7A282B90@codespeak.net> Author: afa Date: Sun Mar 21 18:04:09 2010 New Revision: 72500 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/pyerrors.h pypy/trunk/pypy/module/cpyext/include/tupleobject.h pypy/trunk/pypy/module/cpyext/include/typeobject.c Log: export global symbols from the bridge library Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 18:04:09 2010 @@ -68,6 +68,15 @@ FUNCTIONS = {} TYPES = {} +GLOBALS = { + 'Py_None': ('PyObject*', 'space.w_None'), + 'Py_True': ('PyObject*', 'space.w_True'), + 'Py_False': ('PyObject*', 'space.w_False'), + 'PyExc_Exception': ('PyObject*', 'space.w_Exception'), + 'PyExc_TypeError': ('PyObject*', 'space.w_TypeError'), + 'PyType_Type': ('PyTypeObject*', 'space.w_type'), + 'PyBaseObject_Type': ('PyTypeObject*', 'space.w_object'), + } # It is important that these PyObjects are allocated in a raw fashion # Thus we cannot save a forward pointer to the wrapped object @@ -124,7 +133,7 @@ def build_bridge(space, rename=True): db = LowLevelDatabase() - export_symbols = list(FUNCTIONS) + export_symbols = list(FUNCTIONS) + list(GLOBALS) structindex = {} @@ -135,11 +144,12 @@ """ if rename: pypy_rename = [] - export_symbols = [] - for name in FUNCTIONS: + renamed_symbols = [] + for name in export_symbols: newname = name.replace('Py', 'PyPy') pypy_rename.append('#define %s %s' % (name, newname)) - export_symbols.append(newname) + renamed_symbols.append(newname) + export_symbols = renamed_symbols pypy_rename_h = udir.join('pypy_rename.h') pypy_rename_h.write('\n'.join(pypy_rename)) @@ -176,18 +186,13 @@ body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) - global_objects = """ - PyObject *PyPy_None = NULL; - PyObject *PyPy_True = NULL; - PyObject *PyPy_False = NULL; - PyObject *PyPyExc_Exception = NULL; - PyObject *PyPyExc_TypeError = NULL; - PyTypeObject *PyPyType_Type = NULL; - PyTypeObject *PyPyBaseObject_Type = NULL; - """ + global_objects = [] + for name, (type, expr) in GLOBALS.iteritems(): + global_objects.append('%s %s = NULL;' % (type, name)) + global_code = '\n'.join(global_objects) code = (prologue + struct_declaration_code + - global_objects + + global_code + '\n' + '\n'.join(functions)) @@ -210,14 +215,10 @@ pypyAPI = ctypes.POINTER(ctypes.c_void_p).in_dll(bridge, 'pypyAPI') # populate static data - for name, w_obj in [("PyPy_None", space.w_None), - ("PyPy_True", space.w_True), - ("PyPy_False", space.w_False), - ("PyPyExc_Exception", space.w_Exception), - ("PyPyExc_TypeError", space.w_TypeError), - ("PyPyType_Type", space.w_type), - ("PyPyBaseObject_Type", space.w_object), - ]: + for name, (type, expr) in GLOBALS.iteritems(): + if rename: + name = name.replace('Py', 'PyPy') + w_obj = eval(expr) ptr = ctypes.c_void_p.in_dll(bridge, name) ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), ctypes.c_void_p).value Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sun Mar 21 18:04:09 2010 @@ -2,16 +2,19 @@ #define Py_PYTHON_H /* Compat stuff */ +#ifndef _WIN32 #include #include -#define Py_ssize_t long #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#else +#define Py_DEPRECATED(VERSION_UNUSED) +#endif +#define Py_ssize_t long #include "object.h" /* move somewhere else */ -extern PyObject *PyPy_None; -#define Py_None PyPy_None +extern PyObject *Py_None; #define long int /* XXX: same hack as in api.py */ Modified: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Sun Mar 21 18:04:09 2010 @@ -7,11 +7,9 @@ extern "C" { #endif -extern PyObject *PyPy_True; -#define Py_True PyPy_True +extern PyObject *Py_True; -extern PyObject *PyPy_False; -#define Py_False PyPy_False +extern PyObject *Py_False; /* Macros for returning Py_True or Py_False, respectively */ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sun Mar 21 18:04:09 2010 @@ -34,9 +34,6 @@ #define Py_SIZE(ob) (((PyVarObject*)(ob))->obj_size) -extern PyObject *PyPy_None; -#define Py_None PyPy_None - struct _typeobject; typedef void (*freefunc)(void *); typedef void (*destructor)(PyObject *); @@ -378,12 +375,9 @@ #define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL -extern PyTypeObject *PyPyType_Type; /* built-in 'type' */ -#define PyType_Type *PyPyType_Type -extern PyTypeObject *PyPyBaseObject_Type; -#define PyBaseObject_Type *PyPyBaseObject_Type -int PyPyType_Ready(PyTypeObject *); -#define PyType_Ready PyPyType_Ready +extern PyTypeObject *PyType_Type; /* built-in 'type' */ +extern PyTypeObject *PyBaseObject_Type; +int PyType_Ready(PyTypeObject *); /* objimpl.h ----------------------------------------------*/ Modified: pypy/trunk/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/trunk/pypy/module/cpyext/include/pyerrors.h Sun Mar 21 18:04:09 2010 @@ -7,8 +7,7 @@ extern "C" { #endif -extern PyObject *PyPyExc_Exception; -#define PyExc_Exception PyPyExc_Exception +extern PyObject *PyExc_Exception; #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/tupleobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/tupleobject.h Sun Mar 21 18:04:09 2010 @@ -10,7 +10,6 @@ PyObject * PyTuple_New(Py_ssize_t size); PyObject * PyTuple_Pack(Py_ssize_t, ...); PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); -#define PyTuple_Pack PyPyTuple_Pack #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/include/typeobject.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/typeobject.c (original) +++ pypy/trunk/pypy/module/cpyext/include/typeobject.c Sun Mar 21 18:04:09 2010 @@ -3,9 +3,8 @@ #include #include - int -PyPyType_Ready(PyTypeObject *type) +PyType_Ready(PyTypeObject *type) { PyObject *dict, *bases; PyTypeObject *base; @@ -61,7 +60,7 @@ if (base == NULL) bases = PyTuple_New(0); else - bases = PyTuple_Pack(1, base); + bases = PyPyTuple_Pack(1, base); if (bases == NULL) goto error; type->tp_bases = bases; From xoraxax at codespeak.net Sun Mar 21 18:07:55 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 18:07:55 +0100 (CET) Subject: [pypy-svn] r72502 - pypy/trunk/pypy/module/cpyext/include Message-ID: <20100321170755.171FF282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 18:07:53 2010 New Revision: 72502 Modified: pypy/trunk/pypy/module/cpyext/include/object.h Log: Add the manual rename define. Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Sun Mar 21 18:07:53 2010 @@ -378,6 +378,7 @@ extern PyTypeObject *PyType_Type; /* built-in 'type' */ extern PyTypeObject *PyBaseObject_Type; int PyType_Ready(PyTypeObject *); +#define PyType_Ready PyPyType_Ready /* objimpl.h ----------------------------------------------*/ From benjamin at codespeak.net Sun Mar 21 18:18:47 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 21 Mar 2010 18:18:47 +0100 (CET) Subject: [pypy-svn] r72503 - pypy/trunk/pypy/module/cpyext Message-ID: <20100321171847.CB405282B90@codespeak.net> Author: benjamin Date: Sun Mar 21 18:18:46 2010 New Revision: 72503 Modified: pypy/trunk/pypy/module/cpyext/typeobject.py Log: death to tabs Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 18:18:46 2010 @@ -8,8 +8,8 @@ from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject,\ - PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ + PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State @@ -23,7 +23,7 @@ # XXX PyNumberMethods = PySequenceMethods = PyMappingMethods = \ - PyBufferProcs = PyMemberDef = PyGetSetDef = rffi.VOIDP.TO + PyBufferProcs = PyMemberDef = PyGetSetDef = rffi.VOIDP.TO freefunc = P(FT([rffi.VOIDP], Void)) destructor = P(FT([PyO], Void)) @@ -67,79 +67,79 @@ PyTypeObjectFields.extend(PyObjectFields) PyTypeObjectFields.extend([ ("tp_name", rffi.CCHARP), # For printing, in format "." - ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation + ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation - # Methods to implement standard operations - ("tp_dealloc", destructor), - ("tp_print", printfunc), - ("tp_getattr", getattrfunc), - ("tp_setattr", setattrfunc), - ("tp_compare", cmpfunc), - ("tp_repr", reprfunc), - - # Method suites for standard classes - ("tp_as_number", Ptr(PyNumberMethods)), - ("tp_as_sequence", Ptr(PySequenceMethods)), - ("tp_as_mapping", Ptr(PyMappingMethods)), - - # More standard operations (here for binary compatibility) - ("tp_hash", hashfunc), - ("tp_call", ternaryfunc), - ("tp_str", reprfunc), - ("tp_getattro", getattrofunc), - ("tp_setattro", setattrofunc), - - # Functions to access object as input/output buffer - ("tp_as_buffer", Ptr(PyBufferProcs)), - - # Flags to define presence of optional/expanded features - ("tp_flags", lltype.Signed), - - ("tp_doc", rffi.CCHARP), # Documentation string - - # Assigned meaning in release 2.0 - # call function for all accessible objects - ("tp_traverse", traverseproc), - - # delete references to contained objects - ("tp_clear", inquiry), - - # Assigned meaning in release 2.1 - # rich comparisons - ("tp_richcompare", richcmpfunc), - - # weak reference enabler - ("tp_weaklistoffset", Py_ssize_t), - - # Added in release 2.2 - # Iterators - ("tp_iter", getiterfunc), - ("tp_iternext", iternextfunc), + # Methods to implement standard operations + ("tp_dealloc", destructor), + ("tp_print", printfunc), + ("tp_getattr", getattrfunc), + ("tp_setattr", setattrfunc), + ("tp_compare", cmpfunc), + ("tp_repr", reprfunc), + + # Method suites for standard classes + ("tp_as_number", Ptr(PyNumberMethods)), + ("tp_as_sequence", Ptr(PySequenceMethods)), + ("tp_as_mapping", Ptr(PyMappingMethods)), + + # More standard operations (here for binary compatibility) + ("tp_hash", hashfunc), + ("tp_call", ternaryfunc), + ("tp_str", reprfunc), + ("tp_getattro", getattrofunc), + ("tp_setattro", setattrofunc), + + # Functions to access object as input/output buffer + ("tp_as_buffer", Ptr(PyBufferProcs)), + + # Flags to define presence of optional/expanded features + ("tp_flags", lltype.Signed), + + ("tp_doc", rffi.CCHARP), # Documentation string + + # Assigned meaning in release 2.0 + # call function for all accessible objects + ("tp_traverse", traverseproc), + + # delete references to contained objects + ("tp_clear", inquiry), + + # Assigned meaning in release 2.1 + # rich comparisons + ("tp_richcompare", richcmpfunc), + + # weak reference enabler + ("tp_weaklistoffset", Py_ssize_t), + + # Added in release 2.2 + # Iterators + ("tp_iter", getiterfunc), + ("tp_iternext", iternextfunc), - # Attribute descriptor and subclassing stuff + # Attribute descriptor and subclassing stuff ("tp_methods", Ptr(PyMethodDef)), ("tp_members", Ptr(PyMemberDef)), ("tp_getset", Ptr(PyGetSetDef)), ("tp_base", Ptr(PyTypeObject)), - ("tp_dict", PyObject), - ("tp_descr_get", descrgetfunc), - ("tp_descr_set", descrsetfunc), - ("tp_dictoffset", Py_ssize_t), # can be ignored in PyPy - ("tp_init", initproc), - ("tp_alloc", allocfunc), - ("tp_new", newfunc), - ("tp_free", freefunc), # Low-level free-memory routine - ("tp_is_gc", inquiry), # For PyObject_IS_GC - ("tp_bases", PyObject), - ("tp_mro", PyObject), # method resolution order - ("tp_cache", PyObject), - ("tp_subclasses", PyObject), - ("tp_weaklist", PyObject), - ("tp_del", destructor), + ("tp_dict", PyObject), + ("tp_descr_get", descrgetfunc), + ("tp_descr_set", descrsetfunc), + ("tp_dictoffset", Py_ssize_t), # can be ignored in PyPy + ("tp_init", initproc), + ("tp_alloc", allocfunc), + ("tp_new", newfunc), + ("tp_free", freefunc), # Low-level free-memory routine + ("tp_is_gc", inquiry), # For PyObject_IS_GC + ("tp_bases", PyObject), + ("tp_mro", PyObject), # method resolution order + ("tp_cache", PyObject), + ("tp_subclasses", PyObject), + ("tp_weaklist", PyObject), + ("tp_del", destructor), ]) PyTypeObject = cpython_struct( - "PyTypeObject", - PyTypeObjectFields, PyTypeObject) + "PyTypeObject", + PyTypeObjectFields, PyTypeObject) class W_PyCTypeObject(W_TypeObject): From xoraxax at codespeak.net Sun Mar 21 19:30:58 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 19:30:58 +0100 (CET) Subject: [pypy-svn] r72506 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100321183058.95AAE282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 19:30:56 2010 New Revision: 72506 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/methodobject.h pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/object.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: General progress: added correct allocation code respecting basesize, fix instantiation of objects, extend module support code. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 19:30:56 2010 @@ -40,6 +40,10 @@ #globals().update(rffi_platform.configure(CConfig_constants)) Py_TPFLAGS_READY = (1L<<12) Py_TPFLAGS_READYING = (1L<<13) +METH_COEXIST = 0x0040 +METH_STATIC = 0x0020 +METH_CLASS = 0x0010 +METH_NOARGS = 0x0004 class ApiFunction: @@ -75,7 +79,7 @@ 'PyExc_Exception': ('PyObject*', 'space.w_Exception'), 'PyExc_TypeError': ('PyObject*', 'space.w_TypeError'), 'PyType_Type': ('PyTypeObject*', 'space.w_type'), - 'PyBaseObject_Type': ('PyTypeObject*', 'space.w_object'), + 'PyBaseObject_Type#': ('PyTypeObject*', 'space.w_object'), } # It is important that these PyObjects are allocated in a raw fashion @@ -84,8 +88,10 @@ PyObjectStruct = lltype.ForwardReference() PyObject = lltype.Ptr(PyObjectStruct) PyObjectFields = (("obj_refcnt", lltype.Signed), ("obj_type", PyObject)) +PyVarObjectFields = PyObjectFields + (("obj_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) + def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): if name in TYPES: @@ -97,13 +103,38 @@ class InvalidPointerException(Exception): pass +def get_padded_type(T, size): + fields = T._flds.copy() + hints = T._hints.copy() + hints["size"] = size + del hints["fieldoffsets"] + pad_fields = [] + new_fields = [] + for name in T._names: + new_fields.append((name, fields[name])) + for i in xrange(size - rffi.sizeof(T)): + new_fields.append(("custom%i" % (i, ), lltype.Char)) + hints["padding"] = hints["padding"] + tuple(pad_fields) + return lltype.Struct(hints["c_name"], *new_fields, hints=hints) + def make_ref(space, w_obj, borrowed=False): + if w_obj is None: + return lltype.nullptr(PyObject.TO) + #raise NullPointerException("Trying to pass a NULL reference") state = space.fromcache(State) py_obj = state.py_objects_w2r.get(w_obj) if py_obj is None: + from pypy.module.cpyext.typeobject import allocate_type_obj,\ + W_PyCTypeObject, W_PyCObject if space.is_w(space.type(w_obj), space.w_type): - from pypy.module.cpyext.typeobject import allocate_type_obj py_obj = allocate_type_obj(space, w_obj) + elif isinstance(w_obj, W_PyCObject): + w_type = space.type(w_obj) + assert isinstance(w_type, W_PyCTypeObject) + pto = w_type.pto + basicsize = pto._obj.c_tp_basicsize + T = get_padded_type(PyObject.TO, basicsize) + py_obj = lltype.malloc(T, None, flavor="raw") else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") py_obj.c_obj_refcnt = 1 @@ -124,6 +155,7 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: + import pdb; pdb.set_trace() raise InvalidPointerException("Got invalid reference to a PyObject") return obj @@ -146,8 +178,13 @@ pypy_rename = [] renamed_symbols = [] for name in export_symbols: + if "#" in name: + deref = "*" + else: + deref = "" + name = name.replace("#", "") newname = name.replace('Py', 'PyPy') - pypy_rename.append('#define %s %s' % (name, newname)) + pypy_rename.append('#define %s %s%s' % (name, deref, newname)) renamed_symbols.append(newname) export_symbols = renamed_symbols pypy_rename_h = udir.join('pypy_rename.h') @@ -188,7 +225,7 @@ global_objects = [] for name, (type, expr) in GLOBALS.iteritems(): - global_objects.append('%s %s = NULL;' % (type, name)) + global_objects.append('%s %s = NULL;' % (type, name.replace("#", ""))) global_code = '\n'.join(global_objects) code = (prologue + struct_declaration_code + @@ -216,6 +253,7 @@ # populate static data for name, (type, expr) in GLOBALS.iteritems(): + name = name.replace("#", "") if rename: name = name.replace('Py', 'PyPy') w_obj = eval(expr) Modified: pypy/trunk/pypy/module/cpyext/include/methodobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/methodobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/methodobject.h Sun Mar 21 19:30:56 2010 @@ -29,6 +29,20 @@ #define METH_NOARGS 0x0004 #define METH_O 0x0008 +/* METH_CLASS and METH_STATIC are a little different; these control + the construction of methods for a class. These cannot be used for + functions in modules. */ +#define METH_CLASS 0x0010 +#define METH_STATIC 0x0020 + +/* METH_COEXIST allows a method to be entered eventhough a slot has + already filled the entry. When defined, the flag allows a separate + method, "__contains__" for example, to coexist with a defined + slot like sq_contains. */ + +#define METH_COEXIST 0x0040 + + #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sun Mar 21 19:30:56 2010 @@ -5,7 +5,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ - InvalidPointerException + InvalidPointerException, make_ref from pypy.module.cpyext.state import State from pypy.rlib.objectmodel import we_are_translated @@ -19,10 +19,14 @@ def cfunction_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) args_w, kw_w = __args__.unpack() - null = lltype.nullptr(PyObject.TO) # XXX for the moment + w_kw = space.newdict() + for key, w_value in kw_w: + space.setitem(w_kw, space.wrap(key), w_value) + args_tuple = space.newtuple([space.wrap(args_w), w_kw]) + #null = lltype.nullptr(PyObject.TO) # XXX for the moment # Call the C function - result = self.ml.c_ml_meth(null, null) + result = self.ml.c_ml_meth(make_ref(space, self.w_self), make_ref(space, args_tuple)) try: ret = from_ref(space, result) except NullPointerException: Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 19:30:56 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject +from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ + METH_STATIC, METH_CLASS, METH_COEXIST from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @@ -25,26 +26,43 @@ def Py_InitModule(space, name, methods): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) - dict_w = convert_method_defs(space, methods) + dict_w = convert_method_defs(space, methods, None) for key, w_value in dict_w.items(): space.setattr(w_mod, space.wrap(key), w_value) return w_mod -def convert_method_defs(space, methods): +def convert_method_defs(space, methods, pto): methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) dict_w = {} if methods: - i = 0 + i = -1 while True: + i = i + 1 method = methods[i] if not method.c_ml_name: break methodname = rffi.charp2str(method.c_ml_name) flags = method.c_ml_flags - w_function = PyCFunction_NewEx(space, method, None) - dict_w[methodname] = w_function - i = i + 1 + if pto is None: + if flags & METH_CLASS or flags & METH_STATIC: + raise OperationError(space.w_ValueError, + "module functions cannot set METH_CLASS or METH_STATIC") + w_obj = PyCFunction_NewEx(space, method, None) + else: + if methodname in dict_w and not (flags & METH_COEXIST): + continue + if flags & METH_CLASS: + if flags & METH_STATIC: + raise OperationError(space.w_ValueError, + "method cannot be both class and static") + w_obj = PyDescr_NewClassMethod(pto, method) + elif flags & METH_STATIC: + w_func = PyCFunction_NewEx(space, method, None) + w_obj = PyStaticMethod_New(space, w_func) + else: + w_obj = PyDescr_NewMethod(space, pto, method) + dict_w[methodname] = w_obj return dict_w Modified: pypy/trunk/pypy/module/cpyext/object.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/object.py (original) +++ pypy/trunk/pypy/module/cpyext/object.py Sun Mar 21 19:30:56 2010 @@ -3,14 +3,13 @@ from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject -def get_cls_for_type_object(space, w_type): - if isinstance(w_type, W_PyCTypeObject): - return space.allocate_instance(W_PyCObject, w_type) - assert False, "Please add more cases in get_cls_for_type_object!" @cpython_api([PyObject], PyObject) def _PyObject_New(space, w_type): - return get_cls_for_type_object(space, w_type) + if isinstance(w_type, W_PyCTypeObject): + w_pycobj = space.allocate_instance(W_PyCObject, w_type) + return w_pycobj + assert False, "Please add more cases in get_cls_for_type_object!" @cpython_api([rffi.VOIDP_real], lltype.Void) def PyObject_Del(space, w_obj): Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sun Mar 21 19:30:56 2010 @@ -25,6 +25,11 @@ assert api.FUNCTIONS['Py_InitModule'].argtypes == [ rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] + def test_padding(self): + T = api.get_padded_type(api.PyObject.TO, 42) + assert rffi.sizeof(T) == 42 + print T + def compile_module(modname, **kwds): eci = ExternalCompilationInfo( export_symbols=['init%s' % (modname,)], Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 19:30:56 2010 @@ -64,7 +64,7 @@ traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT)) PyTypeObjectFields = [] -PyTypeObjectFields.extend(PyObjectFields) +PyTypeObjectFields.extend(PyVarObjectFields) PyTypeObjectFields.extend([ ("tp_name", rffi.CCHARP), # For printing, in format "." ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation @@ -143,9 +143,14 @@ class W_PyCTypeObject(W_TypeObject): - pass + def __init__(self, space, pto): + self.pto = pto + bases_w = [] + dict_w = convert_method_defs(space, pto.c_tp_methods, pto) + W_TypeObject.__init__(self, space, rffi.charp2str(pto.c_tp_name), + bases_w or [space.w_object], dict_w) -class W_PyCObject(W_ObjectObject): +class W_PyCObject(Wrappable): pass @unwrap_spec(ObjSpace, W_Root, W_Root) @@ -160,12 +165,9 @@ return pto def create_type_object(space, pto): - bases_w = [] - dict_w = convert_method_defs(space, pto.c_tp_methods) w_type = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) - W_TypeObject.__init__(w_type, space, rffi.charp2str(pto.c_tp_name), - bases_w or [space.w_object], dict_w) + w_type.__init__(space, pto) w_type.ready() return w_type @@ -180,10 +182,11 @@ state.py_objects_w2r[w_obj] = pto return 1 -W_PyCObject.typedef = TypeDef( - 'C_object', - #__getattrbute__ = interp2app(cobject_descr_getattribute), - ) +W_PyCObject.typedef = W_ObjectObject.typedef +#TypeDef( +# 'C_object', +# #__getattrbute__ = interp2app(cobject_descr_getattribute), +# ) W_PyCTypeObject.typedef = TypeDef( 'C_type', W_TypeObject.typedef From xoraxax at codespeak.net Sun Mar 21 19:31:51 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 19:31:51 +0100 (CET) Subject: [pypy-svn] r72507 - pypy/trunk/pypy/module/cpyext Message-ID: <20100321183151.B15B3282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 19:31:50 2010 New Revision: 72507 Modified: pypy/trunk/pypy/module/cpyext/typeobject.py Log: Fix NameError. Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Sun Mar 21 19:31:50 2010 @@ -9,7 +9,7 @@ from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - PyObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY + PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State From xoraxax at codespeak.net Sun Mar 21 20:20:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 20:20:20 +0100 (CET) Subject: [pypy-svn] r72508 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100321192020.06A06282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 20:20:19 2010 New Revision: 72508 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Log: General progress, first module works nearly completely! Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 20:20:19 2010 @@ -141,6 +141,7 @@ ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) + py_obj = rffi.cast(PyObject, py_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj elif not borrowed: Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sun Mar 21 20:20:19 2010 @@ -3,6 +3,7 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.function import BuiltinFunction, descr_function_get from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ InvalidPointerException, make_ref @@ -10,11 +11,40 @@ from pypy.rlib.objectmodel import we_are_translated +# XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): - def __init__(self, ml, w_self): + acceptable_as_base_class = False + def __init__(self, space, ml, w_self): + self.space = space self.ml = ml self.w_self = w_self + def call(self, w_self, args_tuple): + space = self.space + # Call the C function + if w_self is None: + w_self = self.w_self + result = self.ml.c_ml_meth(make_ref(space, w_self), make_ref(space, args_tuple)) + try: + ret = from_ref(space, result) + except NullPointerException: + state = space.fromcache(State) + state.check_and_raise_exception() + assert False, "NULL returned but no exception set" + except InvalidPointerException: + if not we_are_translated(): + import sys + print >>sys.stderr, "Calling a C function return an invalid PyObject" \ + " pointer." + raise + return ret + +class W_PyCMethodObject(W_PyCFunctionObject): + def __init__(self, space, ml): + self.space = space + self.ml = ml + + @unwrap_spec(ObjSpace, W_Root, Arguments) def cfunction_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) @@ -24,29 +54,40 @@ space.setitem(w_kw, space.wrap(key), w_value) args_tuple = space.newtuple([space.wrap(args_w), w_kw]) #null = lltype.nullptr(PyObject.TO) # XXX for the moment + ret = self.call(None, args_tuple) + # XXX result.decref() + return ret - # Call the C function - result = self.ml.c_ml_meth(make_ref(space, self.w_self), make_ref(space, args_tuple)) - try: - ret = from_ref(space, result) - except NullPointerException: - state = space.fromcache(State) - state.check_and_raise_exception() - assert False, "NULL returned but no exception set" - except InvalidPointerException: - if not we_are_translated(): - import sys - print >>sys.stderr, "Calling a C function return an invalid PyObject" \ - " pointer." - raise - + at unwrap_spec(ObjSpace, W_Root, Arguments) +def cmethod_descr_call(space, w_self, __args__): + self = space.interp_w(W_PyCFunctionObject, w_self) + args_w, kw_w = __args__.unpack() + w_kw = space.newdict() + for key, w_value in kw_w: + space.setitem(w_kw, space.wrap(key), w_value) + args_tuple = space.newtuple([space.wrap(args_w[1:]), w_kw]) + ret = self.call(args_w[0], args_tuple) # XXX result.decref() return ret + W_PyCFunctionObject.typedef = TypeDef( - 'builtin_function_or_method', + 'builtin_function', __call__ = interp2app(cfunction_descr_call), + __get__ = interp2app(descr_function_get), + ) + +W_PyCMethodObject.typedef = TypeDef( + 'builtin_method', + __get__ = interp2app(descr_function_get), + __call__ = interp2app(cmethod_descr_call), ) -def PyCFunction_NewEx(space, ml, w_self): - return space.wrap(W_PyCFunctionObject(ml, w_self)) + +def PyCFunction_NewEx(space, ml, w_self): # not directly the API sig + return space.wrap(W_PyCFunctionObject(space, ml, w_self)) + + +def PyDescr_NewMethod(space, pto, method): + return space.wrap(W_PyCMethodObject(space, method)) + Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 20:20:19 2010 @@ -2,7 +2,7 @@ from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ METH_STATIC, METH_CLASS, METH_COEXIST from pypy.interpreter.module import Module -from pypy.module.cpyext.methodobject import PyCFunction_NewEx +from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Sun Mar 21 20:20:19 2010 @@ -5,15 +5,15 @@ class AppTestTypeObject(AppTestCpythonExtensionBase): def test_typeobject(self): - skip("In progress") import sys module = self.import_module(name='foo') assert 'foo' in sys.modules assert "copy" in dir(module.fooType) - print module.fooType.copy obj = module.new() print "Obj has type", type(obj) assert type(obj) is module.fooType print "type of obj has type", type(type(obj)) obj2 = obj.copy() + skip("In progress") + assert "copy" in repr(module.fooType.copy) assert module.new().name == "Foo Example" From xoraxax at codespeak.net Sun Mar 21 21:14:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 21:14:20 +0100 (CET) Subject: [pypy-svn] r72509 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100321201420.BE82C282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 21:14:11 2010 New Revision: 72509 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/boolobject.py pypy/trunk/pypy/module/cpyext/include/tupleobject.h pypy/trunk/pypy/module/cpyext/macros.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Simplify code, fix translation error, add refcounting test. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 21:14:11 2010 @@ -160,6 +160,10 @@ raise InvalidPointerException("Got invalid reference to a PyObject") return obj +def general_check(space, w_obj, w_type): + w_obj_type = space.type(w_obj) + return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) + #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions Modified: pypy/trunk/pypy/module/cpyext/boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/boolobject.py Sun Mar 21 21:14:11 2010 @@ -1,11 +1,10 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject +from pypy.module.cpyext.api import cpython_api, PyObject, general_check @cpython_api([PyObject], rffi.INT) def PyBool_Check(space, w_obj): - if space.eq_w(space.type(w_obj), space.w_bool): - return 1 - return 0 + w_type = space.w_bool + return general_check(space, w_obj, w_type) @cpython_api([rffi.LONG], PyObject) def PyBool_FromLong(space, value): Modified: pypy/trunk/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/tupleobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/tupleobject.h Sun Mar 21 21:14:11 2010 @@ -9,7 +9,7 @@ PyObject * PyTuple_New(Py_ssize_t size); PyObject * PyTuple_Pack(Py_ssize_t, ...); -PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +int PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sun Mar 21 21:14:11 2010 @@ -5,7 +5,7 @@ from pypy.module.cpyext.state import State # XXX Optimize these functions and put them into macro definitions - at cpython_api([PyObject], lltype.Void) + at cpython_api([PyObject], lltype.Void, borrowed=True) def Py_DECREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) @@ -20,8 +20,9 @@ assert obj.c_obj_refcnt > 0 return - at cpython_api([PyObject], lltype.Void) + at cpython_api([PyObject], lltype.Void, borrowed=True) def Py_INCREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) obj.c_obj_refcnt += 1 + Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Sun Mar 21 21:14:11 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - METH_STATIC, METH_CLASS, METH_COEXIST + METH_STATIC, METH_CLASS, METH_COEXIST, general_check from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @@ -69,8 +69,7 @@ @cpython_api([PyObject], rffi.INT) def PyModule_Check(space, w_obj): w_type = space.gettypeobject(Module.typedef) - w_obj_type = space.type(w_obj) - return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) + return general_check(space, w_obj, w_type) @cpython_api([PyObject], PyObject) def PyModule_GetDict(space, w_mod): Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sun Mar 21 21:14:11 2010 @@ -185,6 +185,34 @@ assert exc.value.message == "moo!" + def test_refcount(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + static PyObject* foo_pi(PyObject* self, PyObject *args) + { + PyObject *true = Py_True; + int refcnt = Py_REFCNT(true); + int refcnt_after; + Py_INCREF(true); + PyBool_Check(true); + Py_DECREF(true); + refcnt_after = Py_REFCNT(true); + printf("REFCNT %i %i\\n", refcnt, refcnt_after); + return PyBool_FromLong(refcnt_after == refcnt); + } + static PyMethodDef methods[] = { + { "test_refcount", foo_pi, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert module.test_refcount() + + def test_init_exception(self): import sys init = """ From xoraxax at codespeak.net Sun Mar 21 21:17:34 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 21:17:34 +0100 (CET) Subject: [pypy-svn] r72510 - pypy/trunk/pypy/module/cpyext Message-ID: <20100321201734.240EF282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 21:17:32 2010 New Revision: 72510 Modified: pypy/trunk/pypy/module/cpyext/macros.py Log: Reverted stupid change, thanks amaury. Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sun Mar 21 21:17:32 2010 @@ -5,7 +5,7 @@ from pypy.module.cpyext.state import State # XXX Optimize these functions and put them into macro definitions - at cpython_api([PyObject], lltype.Void, borrowed=True) + at cpython_api([PyObject], lltype.Void) def Py_DECREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) @@ -20,7 +20,7 @@ assert obj.c_obj_refcnt > 0 return - at cpython_api([PyObject], lltype.Void, borrowed=True) + at cpython_api([PyObject], lltype.Void) def Py_INCREF(space, w_obj): state = space.fromcache(State) obj = state.py_objects_w2r.get(w_obj) From xoraxax at codespeak.net Sun Mar 21 21:20:39 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 21:20:39 +0100 (CET) Subject: [pypy-svn] r72511 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100321202039.2E4FA282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 21:20:37 2010 New Revision: 72511 Modified: pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Sprinkle a refcnt-- into the code, looks more correct now :-) Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sun Mar 21 21:20:37 2010 @@ -26,6 +26,8 @@ w_self = self.w_self result = self.ml.c_ml_meth(make_ref(space, w_self), make_ref(space, args_tuple)) try: + if result: + result.c_obj_refcnt -= 1 ret = from_ref(space, result) except NullPointerException: state = space.fromcache(State) Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sun Mar 21 21:20:37 2010 @@ -202,7 +202,7 @@ Py_DECREF(true); refcnt_after = Py_REFCNT(true); printf("REFCNT %i %i\\n", refcnt, refcnt_after); - return PyBool_FromLong(refcnt_after == refcnt); + return PyBool_FromLong(refcnt_after == refcnt && refcnt < 3); } static PyMethodDef methods[] = { { "test_refcount", foo_pi, METH_NOARGS }, From xoraxax at codespeak.net Sun Mar 21 22:42:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 22:42:03 +0100 (CET) Subject: [pypy-svn] r72512 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100321214203.A640D282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 22:42:01 2010 New Revision: 72512 Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/macros.py pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/state.py pypy/trunk/pypy/module/cpyext/test/test_boolobject.py pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Fix refcounting at various places and instantiate the bridge only once! Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Sun Mar 21 22:42:01 2010 @@ -15,7 +15,7 @@ """NOT_RPYTHON""" state = self.space.fromcache(State) if not we_are_translated(): - state.api_lib = str(pypy.module.cpyext.api.build_bridge(space)) + state.api_lib = str(pypy.module.cpyext.api.build_bridge(self.space)) else: XXX # build an import library when translating pypy. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Sun Mar 21 22:42:01 2010 @@ -156,10 +156,18 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: - import pdb; pdb.set_trace() - raise InvalidPointerException("Got invalid reference to a PyObject") + raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) return obj +def clear_memory(space): + from pypy.module.cpyext.macros import Py_DECREF + state = space.fromcache(State) + while state.py_objects_w2r: + key = state.py_objects_w2r.keys()[0] + Py_DECREF(space, key) + state.reset() + + def general_check(space, w_obj, w_type): w_obj_type = space.type(w_obj) return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) Modified: pypy/trunk/pypy/module/cpyext/macros.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/macros.py (original) +++ pypy/trunk/pypy/module/cpyext/macros.py Sun Mar 21 22:42:01 2010 @@ -8,7 +8,7 @@ @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, w_obj): state = space.fromcache(State) - obj = state.py_objects_w2r.get(w_obj) + obj = state.py_objects_w2r[w_obj] obj.c_obj_refcnt -= 1 if obj.c_obj_refcnt == 0: del state.py_objects_w2r[w_obj] Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Sun Mar 21 22:42:01 2010 @@ -8,6 +8,7 @@ from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ InvalidPointerException, make_ref from pypy.module.cpyext.state import State +from pypy.module.cpyext.macros import Py_DECREF from pypy.rlib.objectmodel import we_are_translated @@ -26,9 +27,11 @@ w_self = self.w_self result = self.ml.c_ml_meth(make_ref(space, w_self), make_ref(space, args_tuple)) try: - if result: - result.c_obj_refcnt -= 1 ret = from_ref(space, result) + Py_DECREF(space, ret) + if w_self: + Py_DECREF(space, w_self) + Py_DECREF(space, args_tuple) except NullPointerException: state = space.fromcache(State) state.check_and_raise_exception() Modified: pypy/trunk/pypy/module/cpyext/state.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/state.py (original) +++ pypy/trunk/pypy/module/cpyext/state.py Sun Mar 21 22:42:01 2010 @@ -4,6 +4,9 @@ class State: def __init__(self, space): + self.reset() + + def reset(self): self.py_objects_w2r = identity_dict() # w_obj -> raw PyObject self.py_objects_r2w = {} # addr of raw PyObject -> w_obj self.exc_type = None @@ -18,3 +21,7 @@ op_err = OperationError(exc_type, exc_value) raise op_err + def print_refcounts(self): + print "REFCOUNTS" + for w_obj, obj in self.py_objects_w2r.items(): + print "%r: %i" % (w_obj, obj.c_obj_refcnt) Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Sun Mar 21 22:42:01 2010 @@ -64,3 +64,4 @@ assert module.get_false() == False assert module.test_FromLong() == True assert module.test_Check() == True + self.check_refcnts("FOOOOOO %r") Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Sun Mar 21 22:42:01 2010 @@ -8,6 +8,8 @@ from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator import platform from pypy.module.cpyext import api +from pypy.module.cpyext.state import State +from pypy.module.cpyext.macros import Py_DECREF from pypy.translator.goal import autopath @@ -44,7 +46,7 @@ class AppTestCpythonExtensionBase: def setup_class(cls): - cls.api_library = api.build_bridge(cls.space, rename=True) + cls.space = gettestobjspace(usemodules=['cpyext']) def import_module(self, name, init=None, body=''): if init is not None: @@ -63,10 +65,12 @@ / 'cpyext'/ 'test' / (name + ".c") kwds = dict(separate_module_files=[filename]) + state = self.space.fromcache(State) + api_library = state.api_lib if sys.platform == 'win32': - kwds["libraries"] = [self.api_library] + kwds["libraries"] = [api_library] else: - kwds["link_files"] = [str(self.api_library + '.so')] + kwds["link_files"] = [str(api_library + '.so')] mod = compile_module(name, **kwds) api.load_extension_module(self.space, mod, name) @@ -76,13 +80,29 @@ def setup_method(self, func): self.w_import_module = self.space.wrap(self.import_module) + self.w_check_refcnts = self.space.wrap(self.check_refcnts) + #self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!") + #self.space.fromcache(State).print_refcounts() def teardown_method(self, func): try: + w_mod = self.space.getitem(self.space.sys.get('modules'), + self.space.wrap('foo')) self.space.delitem(self.space.sys.get('modules'), self.space.wrap('foo')) + Py_DECREF(self.space, w_mod) except OperationError: pass + self.space.fromcache(State).print_refcounts() + #self.check_refcnts("Test leaks object: %r") + + def check_refcnts(self, message): + # check for sane refcnts + for w_obj in (self.space.w_True, self.space.w_False, + self.space.w_None): + state = self.space.fromcache(State) + obj = state.py_objects_w2r.get(w_obj) + assert obj.c_obj_refcnt == 1, message % (w_obj, ) class AppTestCpythonExtension(AppTestCpythonExtensionBase): def test_createmodule(self): @@ -128,8 +148,8 @@ { if (my_objects[0] == NULL) { my_objects[0] = PyFloat_FromDouble(3.14); - Py_INCREF(my_objects[0]); } + Py_INCREF(my_objects[0]); return my_objects[0]; } static PyObject* foo_drop_pi(PyObject* self, PyObject *args) @@ -154,10 +174,16 @@ """ module = self.import_module(name='foo', init=init, body=body) assert module.return_pi() == 3.14 + print "A" module.drop_pi() + print "B" module.drop_pi() + print "C" assert module.return_pi() == 3.14 + print "D" assert module.return_pi() == 3.14 + print "E" + module.drop_pi() skip("Hmm, how to check for the exception?") raises(api.InvalidPointerException, module.return_invalid_pointer) @@ -198,11 +224,13 @@ int refcnt = Py_REFCNT(true); int refcnt_after; Py_INCREF(true); + Py_INCREF(true); PyBool_Check(true); - Py_DECREF(true); refcnt_after = Py_REFCNT(true); + Py_DECREF(true); + Py_DECREF(true); printf("REFCNT %i %i\\n", refcnt, refcnt_after); - return PyBool_FromLong(refcnt_after == refcnt && refcnt < 3); + return PyBool_FromLong(refcnt_after == refcnt+2 && refcnt < 3); } static PyMethodDef methods[] = { { "test_refcount", foo_pi, METH_NOARGS }, From xoraxax at codespeak.net Sun Mar 21 22:56:53 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 21 Mar 2010 22:56:53 +0100 (CET) Subject: [pypy-svn] r72513 - pypy/trunk/pypy/module/cpyext/include Message-ID: <20100321215653.C361E282B90@codespeak.net> Author: xoraxax Date: Sun Mar 21 22:56:52 2010 New Revision: 72513 Modified: pypy/trunk/pypy/module/cpyext/include/Python.h Log: Add include. Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Sun Mar 21 22:56:52 2010 @@ -5,6 +5,7 @@ #ifndef _WIN32 #include #include +#include #define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) #else #define Py_DEPRECATED(VERSION_UNUSED) From xoraxax at codespeak.net Mon Mar 22 00:02:53 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 00:02:53 +0100 (CET) Subject: [pypy-svn] r72514 - in pypy/trunk/pypy: rpython/lltypesystem translator/c translator/c/test Message-ID: <20100321230253.45431282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 00:02:51 2010 New Revision: 72514 Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py pypy/trunk/pypy/translator/c/primitive.py pypy/trunk/pypy/translator/c/test/test_database.py Log: Introduce a real INT type, called INT_real. Bad name, eh? Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py Mon Mar 22 00:02:51 2010 @@ -378,6 +378,8 @@ NUMBER_TYPES = setup() platform.numbertype_to_rclass[lltype.Signed] = int # avoid "r_long" for common cases +INT_real = lltype.Number("INT", INT._type) + # ^^^ this creates at least the following names: # -------------------------------------------------------------------- # Type RPython integer class doing wrap-around Modified: pypy/trunk/pypy/translator/c/primitive.py ============================================================================== --- pypy/trunk/pypy/translator/c/primitive.py (original) +++ pypy/trunk/pypy/translator/c/primitive.py Mon Mar 22 00:02:51 2010 @@ -202,6 +202,7 @@ define_c_primitive(rffi.SHORT, 'short') define_c_primitive(rffi.USHORT, 'unsigned short') define_c_primitive(rffi.INT, 'int') +define_c_primitive(rffi.INT_real, 'int') define_c_primitive(rffi.UINT, 'unsigned int') define_c_primitive(rffi.LONG, 'long', 'L') define_c_primitive(rffi.ULONG, 'unsigned long', 'UL') Modified: pypy/trunk/pypy/translator/c/test/test_database.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_database.py (original) +++ pypy/trunk/pypy/translator/c/test/test_database.py Mon Mar 22 00:02:51 2010 @@ -5,7 +5,7 @@ from pypy.objspace.flow.model import Constant, Variable, SpaceOperation from pypy.objspace.flow.model import Block, Link, FunctionGraph from pypy.rpython.typesystem import getfunctionptr -from pypy.rpython.lltypesystem.rffi import VOIDP_real +from pypy.rpython.lltypesystem.rffi import VOIDP_real, INT_real, INT def dump_on_stdout(database): @@ -227,6 +227,14 @@ db = LowLevelDatabase() assert db.gettype(A) == "void *@" +def test_intlong_unique(): + A = INT_real + B = Signed + db = LowLevelDatabase() + assert db.gettype(A) == "int @" + assert db.gettype(B) == "long @" + + def test_recursive_struct(): S = GcForwardReference() S.become(GcStruct('testing', ('p', Ptr(S)))) From xoraxax at codespeak.net Mon Mar 22 00:58:27 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 00:58:27 +0100 (CET) Subject: [pypy-svn] r72515 - in pypy/trunk/pypy: rlib rpython/lltypesystem Message-ID: <20100321235827.D0777282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 00:58:25 2010 New Revision: 72515 Modified: pypy/trunk/pypy/rlib/rarithmetic.py pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py pypy/trunk/pypy/rpython/lltypesystem/rffi.py Log: Build INT_real a bit differently. Modified: pypy/trunk/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/trunk/pypy/rlib/rarithmetic.py (original) +++ pypy/trunk/pypy/rlib/rarithmetic.py Mon Mar 22 00:58:25 2010 @@ -321,12 +321,13 @@ _inttypes = {} -def build_int(name, sign, bits): +def build_int(name, sign, bits, force_creation=False): sign = bool(sign) - try: - return _inttypes[sign, bits] - except KeyError: - pass + if not force_creation: + try: + return _inttypes[sign, bits] + except KeyError: + pass if sign: base_int_type = signed_int else: @@ -334,8 +335,11 @@ mask = (2 ** bits) - 1 if name is None: raise TypeError('No predefined %sint%d'%(['u', ''][sign], bits)) - int_type = _inttypes[sign, bits] = type(name, (base_int_type,), {'MASK': mask, - 'BITS': bits}) + int_type = type(name, (base_int_type,), {'MASK': mask, + 'BITS': bits, + 'SIGN': sign}) + if not force_creation: + _inttypes[sign, bits] = int_type class ForValuesEntry(extregistry.ExtRegistryEntry): _type_ = int_type Modified: pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/ll2ctypes.py Mon Mar 22 00:58:25 2010 @@ -44,6 +44,7 @@ rffi.SHORT: ctypes.c_short, rffi.USHORT: ctypes.c_ushort, rffi.INT: ctypes.c_int, + rffi.INT_real: ctypes.c_int, rffi.UINT: ctypes.c_uint, rffi.LONG: ctypes.c_long, rffi.ULONG: ctypes.c_ulong, Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py Mon Mar 22 00:58:25 2010 @@ -378,7 +378,9 @@ NUMBER_TYPES = setup() platform.numbertype_to_rclass[lltype.Signed] = int # avoid "r_long" for common cases -INT_real = lltype.Number("INT", INT._type) +r_int_real = rarithmetic.build_int("r_int_real", r_int.SIGN, r_int.BITS, True) +INT_real = lltype.build_number("INT", r_int_real) +platform.numbertype_to_rclass[INT_real] = r_int_real # ^^^ this creates at least the following names: # -------------------------------------------------------------------- From xoraxax at codespeak.net Mon Mar 22 00:58:57 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 00:58:57 +0100 (CET) Subject: [pypy-svn] r72516 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100321235857.B0048282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 00:58:55 2010 New Revision: 72516 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/boolobject.py pypy/trunk/pypy/module/cpyext/dictobject.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/pythonrun.py pypy/trunk/pypy/module/cpyext/tupleobject.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: Remove the long int hack! Use INT_real everywhere. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 00:58:55 2010 @@ -185,7 +185,6 @@ prologue = """\ #define const /* cheat */ #include - #define long int /* cheat */ """ if rename: pypy_rename = [] @@ -304,12 +303,14 @@ return if restype is PyObject: return lltype.nullptr(PyObject.TO) - if restype in (lltype.Signed, rffi.INT): - return -1 + if restype in (lltype.Signed, rffi.INT_real): + return rffi.cast(rffi.INT_real, -1) assert False, "Unknown return type" if callable.api_func.restype is PyObject: retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) + if callable.api_func.restype is rffi.INT_real: + retval = rffi.cast(rffi.INT_real, retval) return retval return wrapper Modified: pypy/trunk/pypy/module/cpyext/boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/boolobject.py Mon Mar 22 00:58:55 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, general_check - at cpython_api([PyObject], rffi.INT) + at cpython_api([PyObject], rffi.INT_real) def PyBool_Check(space, w_obj): w_type = space.w_bool return general_check(space, w_obj, w_type) Modified: pypy/trunk/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/dictobject.py (original) +++ pypy/trunk/pypy/module/cpyext/dictobject.py Mon Mar 22 00:58:55 2010 @@ -6,14 +6,14 @@ def PyDict_New(space): return space.newdict() - at cpython_api([PyObject], rffi.INT) + at cpython_api([PyObject], rffi.INT_real) def PyDict_Check(space, w_obj): w_type = space.w_dict w_obj_type = space.type(w_obj) return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) - at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT) + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real) def PyDict_SetItemString(space, w_dict, key_ptr, w_obj): if PyDict_Check(space, w_dict): key = rffi.charp2str(key_ptr) Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Mon Mar 22 00:58:55 2010 @@ -17,7 +17,6 @@ /* move somewhere else */ extern PyObject *Py_None; -#define long int /* XXX: same hack as in api.py */ #include Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Mon Mar 22 00:58:55 2010 @@ -11,7 +11,7 @@ 'PyMethodDef', [('ml_name', rffi.CCHARP), ('ml_meth', PyCFunction), - ('ml_flags', rffi.INT), + ('ml_flags', rffi.INT_real), ]) def PyImport_AddModule(space, name): @@ -66,7 +66,7 @@ return dict_w - at cpython_api([PyObject], rffi.INT) + at cpython_api([PyObject], rffi.INT_real) def PyModule_Check(space, w_obj): w_type = space.gettypeobject(Module.typedef) return general_check(space, w_obj, w_type) Modified: pypy/trunk/pypy/module/cpyext/pythonrun.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/pythonrun.py (original) +++ pypy/trunk/pypy/module/cpyext/pythonrun.py Mon Mar 22 00:58:55 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api - at cpython_api([], rffi.INT) + at cpython_api([], rffi.INT_real) def Py_IsInitialized(space): return 1 Modified: pypy/trunk/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/tupleobject.py (original) +++ pypy/trunk/pypy/module/cpyext/tupleobject.py Mon Mar 22 00:58:55 2010 @@ -7,7 +7,7 @@ def PyTuple_New(space, size): return space.newtuple([space.w_None] * size) - at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT) + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real) def PyTuple_SetItem(space, w_t, pos, w_obj): assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Mon Mar 22 00:58:55 2010 @@ -27,41 +27,41 @@ freefunc = P(FT([rffi.VOIDP], Void)) destructor = P(FT([PyO], Void)) -printfunc = P(FT([PyO, rffi.VOIDP, rffi.INT], rffi.INT)) +printfunc = P(FT([PyO, rffi.VOIDP, rffi.INT_real], rffi.INT)) getattrfunc = P(FT([PyO, rffi.CCHARP], PyO)) getattrofunc = P(FT([PyO, PyO], PyO)) -setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT)) -setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT)) -cmpfunc = P(FT([PyO, PyO], rffi.INT)) +setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT_real)) +setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) +cmpfunc = P(FT([PyO, PyO], rffi.INT_real)) reprfunc = P(FT([PyO], PyO)) hashfunc = P(FT([PyO], lltype.Signed)) -richcmpfunc = P(FT([PyO, PyO, rffi.INT], PyO)) +richcmpfunc = P(FT([PyO, PyO, rffi.INT_real], PyO)) getiterfunc = P(FT([PyO], PyO)) iternextfunc = P(FT([PyO], PyO)) descrgetfunc = P(FT([PyO, PyO, PyO], PyO)) -descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT)) -initproc = P(FT([PyO, PyO, PyO], rffi.INT)) +descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) +initproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) newfunc = P(FT([PyTypeObjectPtr, PyO, PyO], PyO)) allocfunc = P(FT([PyTypeObjectPtr, Py_ssize_t], PyO)) unaryfunc = P(FT([PyO], PyO)) binaryfunc = P(FT([PyO, PyO], PyO)) ternaryfunc = P(FT([PyO, PyO, PyO], PyO)) -inquiry = P(FT([PyO], rffi.INT)) +inquiry = P(FT([PyO], rffi.INT_real)) lenfunc = P(FT([PyO], Py_ssize_t)) -coercion = P(FT([PyOPtr, PyOPtr], rffi.INT)) -intargfunc = P(FT([PyO, rffi.INT], PyO)) -intintargfunc = P(FT([PyO, rffi.INT, rffi.INT], PyO)) +coercion = P(FT([PyOPtr, PyOPtr], rffi.INT_real)) +intargfunc = P(FT([PyO, rffi.INT_real], PyO)) +intintargfunc = P(FT([PyO, rffi.INT_real, rffi.INT], PyO)) ssizeargfunc = P(FT([PyO, Py_ssize_t], PyO)) ssizessizeargfunc = P(FT([PyO, Py_ssize_t, Py_ssize_t], PyO)) -intobjargproc = P(FT([PyO, rffi.INT, PyO], rffi.INT)) -intintobjargproc = P(FT([PyO, rffi.INT, rffi.INT, PyO], rffi.INT)) -ssizeobjargproc = P(FT([PyO, Py_ssize_t, PyO], rffi.INT)) -ssizessizeobjargproc = P(FT([PyO, Py_ssize_t, Py_ssize_t, PyO], rffi.INT)) -objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT)) - -objobjproc = P(FT([PyO, PyO], rffi.INT)) -visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT)) -traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT)) +intobjargproc = P(FT([PyO, rffi.INT_real, PyO], rffi.INT)) +intintobjargproc = P(FT([PyO, rffi.INT_real, rffi.INT, PyO], rffi.INT)) +ssizeobjargproc = P(FT([PyO, Py_ssize_t, PyO], rffi.INT_real)) +ssizessizeobjargproc = P(FT([PyO, Py_ssize_t, Py_ssize_t, PyO], rffi.INT_real)) +objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) + +objobjproc = P(FT([PyO, PyO], rffi.INT_real)) +visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT_real)) +traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT_real)) PyTypeObjectFields = [] PyTypeObjectFields.extend(PyVarObjectFields) @@ -172,7 +172,7 @@ return w_type - at cpython_api([PyTypeObjectPtr], rffi.INT) + at cpython_api([PyTypeObjectPtr], rffi.INT_real) def PyPyType_Register(space, pto): state = space.fromcache(State) ptr = ctypes.addressof(pto._obj._storage) From xoraxax at codespeak.net Mon Mar 22 01:29:59 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 01:29:59 +0100 (CET) Subject: [pypy-svn] r72517 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100322002959.50371282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 01:29:57 2010 New Revision: 72517 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py pypy/trunk/pypy/module/cpyext/tupleobject.py Log: Implement reference stealing correctly. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Mon Mar 22 01:29:57 2010 @@ -232,13 +232,31 @@ printf("REFCNT %i %i\\n", refcnt, refcnt_after); return PyBool_FromLong(refcnt_after == refcnt+2 && refcnt < 3); } + static PyObject* foo_bar(PyObject* self, PyObject *args) + { + PyObject *true = Py_True; + PyObject *tup = NULL; + int refcnt = Py_REFCNT(true); + int refcnt_after; + + tup = PyTuple_New(1); + Py_INCREF(true); + if (PyTuple_SetItem(tup, 0, true) < 0) + return NULL; + refcnt_after = Py_REFCNT(true); + printf("REFCNT2 %i %i\\n", refcnt, refcnt_after); + return PyBool_FromLong(refcnt_after == refcnt && refcnt < 3); + } + static PyMethodDef methods[] = { { "test_refcount", foo_pi, METH_NOARGS }, + { "test_refcount2", foo_bar, METH_NOARGS }, { NULL } }; """ module = self.import_module(name='foo', init=init, body=body) assert module.test_refcount() + assert module.test_refcount2() def test_init_exception(self): Modified: pypy/trunk/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/tupleobject.py (original) +++ pypy/trunk/pypy/module/cpyext/tupleobject.py Mon Mar 22 01:29:57 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t +from pypy.module.cpyext.macros import Py_DECREF from pypy.objspace.std.tupleobject import W_TupleObject @@ -11,4 +12,5 @@ def PyTuple_SetItem(space, w_t, pos, w_obj): assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj + Py_DECREF(space, w_obj) # SetItem steals a reference! return 0 From xoraxax at codespeak.net Mon Mar 22 01:56:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 01:56:49 +0100 (CET) Subject: [pypy-svn] r72518 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100322005649.909BC282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 01:56:47 2010 New Revision: 72518 Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/pyerrors.h pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Log: Always create a rename file, found missing decl, err out instead of segfaulting when not having a function declaration. Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Mon Mar 22 01:56:47 2010 @@ -36,4 +36,3 @@ import pypy.module.cpyext.object import pypy.module.cpyext.tupleobject import pypy.module.cpyext.dictobject -api.configure() Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 01:56:47 2010 @@ -175,6 +175,7 @@ #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions +# Do not call this more than once per process def build_bridge(space, rename=True): db = LowLevelDatabase() @@ -186,9 +187,9 @@ #define const /* cheat */ #include """ + pypy_rename = [] + renamed_symbols = [] if rename: - pypy_rename = [] - renamed_symbols = [] for name in export_symbols: if "#" in name: deref = "*" @@ -198,13 +199,11 @@ newname = name.replace('Py', 'PyPy') pypy_rename.append('#define %s %s%s' % (name, deref, newname)) renamed_symbols.append(newname) - export_symbols = renamed_symbols - pypy_rename_h = udir.join('pypy_rename.h') - pypy_rename_h.write('\n'.join(pypy_rename)) - - prologue = """\ - #include /* avoid symbol clashes */ - """ + prologue + export_symbols = renamed_symbols + pypy_rename_h = udir.join('pypy_rename.h') + pypy_rename_h.write('\n'.join(pypy_rename)) + + configure() # needs pypy_rename.h # Structure declaration code members = [] Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Mon Mar 22 01:56:47 2010 @@ -1,6 +1,7 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H +#include /* Compat stuff */ #ifndef _WIN32 #include Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Mon Mar 22 01:56:47 2010 @@ -377,7 +377,7 @@ extern PyTypeObject *PyType_Type; /* built-in 'type' */ extern PyTypeObject *PyBaseObject_Type; -int PyType_Ready(PyTypeObject *); +int PyPyType_Ready(PyTypeObject *); #define PyType_Ready PyPyType_Ready /* objimpl.h ----------------------------------------------*/ Modified: pypy/trunk/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/trunk/pypy/module/cpyext/include/pyerrors.h Mon Mar 22 01:56:47 2010 @@ -8,6 +8,7 @@ #endif extern PyObject *PyExc_Exception; +void PyErr_SetString(PyObject *, char *); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Mon Mar 22 01:56:47 2010 @@ -71,6 +71,7 @@ kwds["libraries"] = [api_library] else: kwds["link_files"] = [str(api_library + '.so')] + kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] mod = compile_module(name, **kwds) api.load_extension_module(self.space, mod, name) From lucian at codespeak.net Mon Mar 22 02:36:50 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Mon, 22 Mar 2010 02:36:50 +0100 (CET) Subject: [pypy-svn] r72519 - pypy/trunk/pypy/translator/platform Message-ID: <20100322013650.28162282B90@codespeak.net> Author: lucian Date: Mon Mar 22 02:36:48 2010 New Revision: 72519 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Switch from .bundle to .dylib for darwin. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Mon Mar 22 02:36:48 2010 @@ -10,7 +10,7 @@ standalone_only = ['-mdynamic-no-pic'] shared_only = [] - so_ext = 'so' + so_ext = 'dylib' def __init__(self, cc=None): if cc is None: @@ -18,7 +18,7 @@ self.cc = cc def _args_for_shared(self, args): - return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + return (self.shared_only + ['-dylib', '-undefined', 'dynamic_lookup'] + args) def include_dirs_for_libffi(self): From lucian at codespeak.net Mon Mar 22 03:11:07 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Mon, 22 Mar 2010 03:11:07 +0100 (CET) Subject: [pypy-svn] r72520 - pypy/trunk/pypy/translator/platform Message-ID: <20100322021107.55B46282B90@codespeak.net> Author: lucian Date: Mon Mar 22 03:11:05 2010 New Revision: 72520 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Revert change from -bundle to -dylib because it breaks many rffi tests. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Mon Mar 22 03:11:05 2010 @@ -10,7 +10,7 @@ standalone_only = ['-mdynamic-no-pic'] shared_only = [] - so_ext = 'dylib' + so_ext = 'so' def __init__(self, cc=None): if cc is None: @@ -18,7 +18,7 @@ self.cc = cc def _args_for_shared(self, args): - return (self.shared_only + ['-dylib', '-undefined', 'dynamic_lookup'] + return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + args) def include_dirs_for_libffi(self): From xoraxax at codespeak.net Mon Mar 22 04:09:42 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 04:09:42 +0100 (CET) Subject: [pypy-svn] r72521 - in pypy/trunk/pypy: interpreter module/cpyext Message-ID: <20100322030942.5B70C282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 04:09:40 2010 New Revision: 72521 Modified: pypy/trunk/pypy/interpreter/argument.py pypy/trunk/pypy/module/cpyext/methodobject.py Log: Refactor call code of cpyext. Modified: pypy/trunk/pypy/interpreter/argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/argument.py (original) +++ pypy/trunk/pypy/interpreter/argument.py Mon Mar 22 04:09:40 2010 @@ -128,6 +128,19 @@ kwds_w[self.keywords[i]] = self.keywords_w[i] return self.arguments_w, kwds_w + def unpack_cpy(self, starting_at=0): + assert starting_at >= 0 + space = self.space + args_w = self.arguments_w + w_kw = space.newdict() + if self.keywords: + for i in range(len(self.keywords)): + space.setitem(w_kw, space.wrap(self.keywords[i]), self.keywords_w[i]) + if starting_at != 0: + args_w = args_w[starting_at:] + args_tuple = space.newtuple([space.wrap(args_w), w_kw]) + return args_tuple + def replace_arguments(self, args_w): "Return a new Arguments with a args_w as positional arguments." return Arguments(self.space, args_w, self.keywords, self.keywords_w) Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Mon Mar 22 04:09:40 2010 @@ -53,25 +53,17 @@ @unwrap_spec(ObjSpace, W_Root, Arguments) def cfunction_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) - args_w, kw_w = __args__.unpack() - w_kw = space.newdict() - for key, w_value in kw_w: - space.setitem(w_kw, space.wrap(key), w_value) - args_tuple = space.newtuple([space.wrap(args_w), w_kw]) - #null = lltype.nullptr(PyObject.TO) # XXX for the moment - ret = self.call(None, args_tuple) + w_tuple = __args__.unpack_cpy() + ret = self.call(None, w_tuple) # XXX result.decref() return ret @unwrap_spec(ObjSpace, W_Root, Arguments) def cmethod_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) - args_w, kw_w = __args__.unpack() - w_kw = space.newdict() - for key, w_value in kw_w: - space.setitem(w_kw, space.wrap(key), w_value) - args_tuple = space.newtuple([space.wrap(args_w[1:]), w_kw]) - ret = self.call(args_w[0], args_tuple) + w_tuple = __args__.unpack_cpy(1) + w_self = __args__.arguments_w[0] + ret = self.call(w_self, w_tuple) # XXX result.decref() return ret From xoraxax at codespeak.net Mon Mar 22 04:38:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 04:38:21 +0100 (CET) Subject: [pypy-svn] r72522 - pypy/trunk/pypy/interpreter/test Message-ID: <20100322033821.69D91282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 04:38:20 2010 New Revision: 72522 Modified: pypy/trunk/pypy/interpreter/test/test_argument.py Log: Add test for unpack_cpy. Modified: pypy/trunk/pypy/interpreter/test/test_argument.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_argument.py (original) +++ pypy/trunk/pypy/interpreter/test/test_argument.py Mon Mar 22 04:38:20 2010 @@ -72,6 +72,9 @@ def newdict(self): return {} + def newlist(self, l=[]): + return l + def setitem(self, obj, key, value): obj[key] = value @@ -90,6 +93,9 @@ def int_w(self, x): return x + def eq_w(self, x, y): + return x == y + def isinstance(self, obj, cls): return isinstance(obj, cls) @@ -129,6 +135,12 @@ assert args1.keywords is args.keywords assert args1.keywords_w is args.keywords_w + def test_unpack_cpy(self): + space = DummySpace() + args = Arguments(space, ["0"]) + assert space.eq_w(args.unpack_cpy(), space.newtuple([space.newlist([space.wrap("0")]), space.newdict()])) + assert space.eq_w(args.unpack_cpy(1), space.newtuple([space.newlist(), space.newdict()])) + def test_fixedunpacked(self): space = DummySpace() From jandem at codespeak.net Mon Mar 22 10:01:44 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Mon, 22 Mar 2010 10:01:44 +0100 (CET) Subject: [pypy-svn] r72523 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322090144.EFABA282B90@codespeak.net> Author: jandem Date: Mon Mar 22 10:01:42 2010 New Revision: 72523 Modified: pypy/trunk/pypy/module/cpyext/TODO Log: This was fixed by xoraxax Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Mon Mar 22 10:01:42 2010 @@ -1,4 +1,3 @@ - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject - Add exceptions - Generate header files programmatically. - - Fix the '#define long int' hack in both api.py and include/Python.h From afa at codespeak.net Mon Mar 22 10:27:54 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 10:27:54 +0100 (CET) Subject: [pypy-svn] r72524 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100322092754.CFF9F282B90@codespeak.net> Author: afa Date: Mon Mar 22 10:27:52 2010 New Revision: 72524 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h pypy/trunk/pypy/module/cpyext/include/boolobject.h pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/include/pyerrors.h Log: Properly dllexport/dllimport globals; this fixes tests on Windows. Also generate the bridge library in the temp dir, not in cpyext/include! Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 10:27:52 2010 @@ -18,7 +18,7 @@ Py_ssize_t = lltype.Signed -include_dir = py.path.local(autopath.pypydir).join('module', 'cpyext', 'include') +include_dir = py.path.local(autopath.pypydir) / 'module' / 'cpyext' / 'include' include_dirs = [ include_dir, udir, @@ -255,6 +255,7 @@ eci = eci.convert_sources_to_files() modulename = platform.platform.compile( [], eci, + outputfilename=str(udir / "module_cache" / "pypyapi"), standalone=False) # load the bridge, and init structure Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Mon Mar 22 10:27:52 2010 @@ -4,19 +4,25 @@ #include /* Compat stuff */ #ifndef _WIN32 -#include -#include -#include -#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +# include +# include +# include +# define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +# define PyAPI_DATA(RTYPE) extern RTYPE #else -#define Py_DEPRECATED(VERSION_UNUSED) +# define Py_DEPRECATED(VERSION_UNUSED) +# ifdef Py_BUILD_CORE +# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE +# else +# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE +# endif #endif #define Py_ssize_t long #include "object.h" /* move somewhere else */ -extern PyObject *Py_None; +PyAPI_DATA(PyObject *) Py_None; #include Modified: pypy/trunk/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/boolobject.h Mon Mar 22 10:27:52 2010 @@ -7,9 +7,8 @@ extern "C" { #endif -extern PyObject *Py_True; - -extern PyObject *Py_False; +PyAPI_DATA(PyObject *) Py_True; +PyAPI_DATA(PyObject *) Py_False; /* Macros for returning Py_True or Py_False, respectively */ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Mon Mar 22 10:27:52 2010 @@ -375,8 +375,8 @@ #define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL -extern PyTypeObject *PyType_Type; /* built-in 'type' */ -extern PyTypeObject *PyBaseObject_Type; +PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; int PyPyType_Ready(PyTypeObject *); #define PyType_Ready PyPyType_Ready Modified: pypy/trunk/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/trunk/pypy/module/cpyext/include/pyerrors.h Mon Mar 22 10:27:52 2010 @@ -7,7 +7,7 @@ extern "C" { #endif -extern PyObject *PyExc_Exception; +PyAPI_DATA(PyObject *) PyExc_Exception; void PyErr_SetString(PyObject *, char *); #ifdef __cplusplus From jandem at codespeak.net Mon Mar 22 11:10:44 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Mon, 22 Mar 2010 11:10:44 +0100 (CET) Subject: [pypy-svn] r72525 - in pypy/trunk/pypy/module/cpyext: . include test Message-ID: <20100322101044.F3889282B90@codespeak.net> Author: jandem Date: Mon Mar 22 11:10:42 2010 New Revision: 72525 Added: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/include/stringobject.h pypy/trunk/pypy/module/cpyext/stringobject.py Log: Add PyString_FromString and string tests Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Mon Mar 22 11:10:42 2010 @@ -34,5 +34,6 @@ import pypy.module.cpyext.pyerrors import pypy.module.cpyext.typeobject import pypy.module.cpyext.object +import pypy.module.cpyext.stringobject import pypy.module.cpyext.tupleobject import pypy.module.cpyext.dictobject Modified: pypy/trunk/pypy/module/cpyext/include/stringobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/stringobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/stringobject.h Mon Mar 22 11:10:42 2010 @@ -8,6 +8,7 @@ #endif PyObject * PyString_FromStringAndSize(const char *, Py_ssize_t); +PyObject * PyString_FromString(const char *); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/stringobject.py Mon Mar 22 11:10:42 2010 @@ -2,12 +2,16 @@ from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, Py_ssize_t @cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) -def PyString_FromStringAndSize(char_p, length): +def PyString_FromStringAndSize(space, char_p, length): l = [] i = 0 while length > 0: - l.append(cp[i]) + l.append(char_p[i]) i += 1 length -= 1 - return "".join(l) + return space.wrap("".join(l)) + at cpython_api([rffi.CCHARP], PyObject) +def PyString_FromString(space, char_p): + s = rffi.charp2str(char_p) + return space.wrap(s) Added: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Mon Mar 22 11:10:42 2010 @@ -0,0 +1,31 @@ +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +import py +import sys + +class AppTestStringObject(AppTestCpythonExtensionBase): + def test_stringobject(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + static PyObject* foo_get_hello1(PyObject* self, PyObject *args) + { + return PyString_FromStringAndSize("Hello world", 11); + } + static PyObject* foo_get_hello2(PyObject* self, PyObject *args) + { + return PyString_FromString("Hello world"); + } + static PyMethodDef methods[] = { + { "get_hello1", foo_get_hello1, METH_NOARGS }, + { "get_hello2", foo_get_hello2, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert 'foo' in sys.modules + assert module.get_hello1() == 'Hello world' + assert module.get_hello2() == 'Hello world' From arigo at codespeak.net Mon Mar 22 11:53:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 11:53:10 +0100 (CET) Subject: [pypy-svn] r72526 - in pypy/trunk/py: impl/code plugin Message-ID: <20100322105310.58F40282B90@codespeak.net> Author: arigo Date: Mon Mar 22 11:53:08 2010 New Revision: 72526 Modified: pypy/trunk/py/impl/code/code.py pypy/trunk/py/plugin/pytest_resultlog.py Log: Revert r72487, which had no effect, and apply instead encode() somewhere else... Modified: pypy/trunk/py/impl/code/code.py ============================================================================== --- pypy/trunk/py/impl/code/code.py (original) +++ pypy/trunk/py/impl/code/code.py Mon Mar 22 11:53:08 2010 @@ -579,7 +579,7 @@ def __str__(self): tw = py.io.TerminalWriter(stringio=True) self.toterminal(tw) - return tw.stringio.getvalue().strip() + return tw.stringio.getvalue().strip().encode('utf-8') def __repr__(self): return "<%s instance at %0x>" %(self.__class__, id(self)) Modified: pypy/trunk/py/plugin/pytest_resultlog.py ============================================================================== --- pypy/trunk/py/plugin/pytest_resultlog.py (original) +++ pypy/trunk/py/plugin/pytest_resultlog.py Mon Mar 22 11:53:08 2010 @@ -68,15 +68,15 @@ else: code = report.shortrepr if code == 'x': - longrepr = safestr(report.longrepr) + longrepr = str(report.longrepr) elif code == 'P': longrepr = '' elif report.passed: longrepr = "" elif report.failed: - longrepr = safestr(report.longrepr) + longrepr = str(report.longrepr) elif report.skipped: - longrepr = safestr(report.longrepr.reprcrash.message) + longrepr = str(report.longrepr.reprcrash.message) self.log_outcome(report.item, code, longrepr) def pytest_collectreport(self, report): @@ -86,16 +86,9 @@ else: assert report.skipped code = "S" - longrepr = safestr(report.longrepr.reprcrash) + longrepr = str(report.longrepr.reprcrash) self.log_outcome(report.collector, code, longrepr) def pytest_internalerror(self, excrepr): path = excrepr.reprcrash.path - self.write_log_entry(path, '!', safestr(excrepr)) - - -def safestr(x): - if isinstance(x, unicode): - return x.encode('utf-8') - else: - return str(x) + self.write_log_entry(path, '!', str(excrepr)) From arigo at codespeak.net Mon Mar 22 11:55:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 11:55:30 +0100 (CET) Subject: [pypy-svn] r72527 - pypy/trunk/pypy/doc/config Message-ID: <20100322105530.0FDD6282B90@codespeak.net> Author: arigo Date: Mon Mar 22 11:55:28 2010 New Revision: 72527 Removed: pypy/trunk/pypy/doc/config/objspace.usemodules._collections.txt Log: Remove this, as 'pypy/module/_collections' is gone. From arigo at codespeak.net Mon Mar 22 12:04:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:04:45 +0100 (CET) Subject: [pypy-svn] r72529 - pypy/trunk/pypy/translator/cli/src Message-ID: <20100322110445.CD21E282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:04:44 2010 New Revision: 72529 Modified: pypy/trunk/pypy/translator/cli/src/pypylib.cs Log: Add the case of receiving a CLI 'long' (i.e. a PyPy 'long long'). 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 Mon Mar 22 12:04:44 2010 @@ -422,6 +422,16 @@ return Convert.ToString(n, base_); } + public static string OOString(long n, int base_) + { + if (base_ == -1) + base_ = 10; + if (n<0 && base_ != 10) + return "-" + Convert.ToString(-n, base_); + else + return Convert.ToString(n, base_); + } + public static string OOString(double d, int base_) { return d.ToString(); From arigo at codespeak.net Mon Mar 22 12:07:22 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:07:22 +0100 (CET) Subject: [pypy-svn] r72530 - pypy/trunk/pypy/translator/jvm/src/pypy Message-ID: <20100322110722.777DC282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:07:20 2010 New Revision: 72530 Modified: pypy/trunk/pypy/translator/jvm/src/pypy/PyPy.java Log: Add the case of receiving a Java 'long' (i.e. a PyPy 'long long'). 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 Mon Mar 22 12:07:20 2010 @@ -839,6 +839,15 @@ return Integer.toString(n, base_); } + public String oostring(long n, int base_) { + if (base_ == -1) + base_ = 10; + if (n < 0 && base_ != 10) + return "-" + Long.toString(-n, base_); + else + return Long.toString(n, base_); + } + public String oostring(double d, int base_) { if (d == Double.POSITIVE_INFINITY) return "inf"; From arigo at codespeak.net Mon Mar 22 12:14:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:14:06 +0100 (CET) Subject: [pypy-svn] r72531 - in pypy/trunk/pypy/translator/c: src test Message-ID: <20100322111406.2ECD5282B9E@codespeak.net> Author: arigo Date: Mon Mar 22 12:14:04 2010 New Revision: 72531 Modified: pypy/trunk/pypy/translator/c/src/llgroup.h pypy/trunk/pypy/translator/c/test/test_lltyped.py Log: Fix test_llgroup_size_limit: * on 32-bit platforms, crash at compile-time again * on 64-bit platforms, disable the test Modified: pypy/trunk/pypy/translator/c/src/llgroup.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/llgroup.h (original) +++ pypy/trunk/pypy/translator/c/src/llgroup.h Mon Mar 22 12:14:04 2010 @@ -19,10 +19,12 @@ #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ ((((char*)groupptr) + skipoffset) + ((long)compactoffset)*4) -/* A macro to check at run-time if sizeof(group) is too large. */ + +/* A macro to crash at compile-time if sizeof(group) is too large. + Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ #define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - if (sizeof(groupname) > 65536*4) \ - error = "group " #groupname " is more than 256KB of data" + { typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 65536*4)-1]; } #else /******************************************************/ Modified: pypy/trunk/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/trunk/pypy/translator/c/test/test_lltyped.py Mon Mar 22 12:14:04 2010 @@ -1,3 +1,4 @@ +import py from pypy.rpython.lltypesystem.lltype import * from pypy.translator.c.test import test_typed @@ -714,9 +715,12 @@ yield self._test_size_limit, False def _test_size_limit(self, toobig): + import sys from pypy.rpython.lltypesystem import llgroup from pypy.rpython.lltypesystem.lloperation import llop from pypy.translator.platform import CompilationError + if toobig and sys.maxint > 2147483647: + py.test.skip("not easy to test groups too big on 64-bit platforms") grp = llgroup.group("big") S1 = Struct('S1', ('x', Signed), ('y', Signed), ('z', Signed), ('u', Signed), From arigo at codespeak.net Mon Mar 22 12:19:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:19:04 +0100 (CET) Subject: [pypy-svn] r72532 - in pypy/trunk/pypy: module/_rawffi module/_rawffi/test rlib rlib/test Message-ID: <20100322111904.10442282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:19:02 2010 New Revision: 72532 Modified: pypy/trunk/pypy/module/_rawffi/array.py pypy/trunk/pypy/module/_rawffi/callback.py pypy/trunk/pypy/module/_rawffi/interp_rawffi.py pypy/trunk/pypy/module/_rawffi/structure.py pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py pypy/trunk/pypy/rlib/libffi.py pypy/trunk/pypy/rlib/test/test_libffi.py Log: Merge branch/rawffi-64: finish and polish the libffi support in module/_rawffi, as needed on 64-bit Intel. This is a bit of a simplification, too. Modified: pypy/trunk/pypy/module/_rawffi/array.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/array.py (original) +++ pypy/trunk/pypy/module/_rawffi/array.py Mon Mar 22 12:19:02 2010 @@ -12,8 +12,9 @@ from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import unwrap_value, wrap_value -from pypy.module._rawffi.interp_rawffi import letter2tp -from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment +from pypy.module._rawffi.interp_rawffi import TYPEMAP +from pypy.module._rawffi.interp_rawffi import size_alignment +from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length from pypy.rlib.rarithmetic import intmask, r_uint def push_elem(ll_array, pos, value): @@ -27,17 +28,25 @@ return ll_array[pos] get_elem._annspecialcase_ = 'specialize:arg(2)' + class W_Array(W_DataShape): - def __init__(self, space, itemtp): - assert isinstance(itemtp, tuple) - self.space = space - self.itemtp = itemtp + def __init__(self, basicffitype, size): + # A W_Array represent the C type '*T', which can also represent + # the type of pointers to arrays of T. So the following fields + # are used to describe T only. It is 'basicffitype' possibly + # repeated until reaching the length 'size'. + self.basicffitype = basicffitype + self.size = size + self.alignment = size_alignment(basicffitype)[1] def allocate(self, space, length, autofree=False): if autofree: return W_ArrayInstanceAutoFree(space, self, length) return W_ArrayInstance(space, self, length) + def get_basic_ffi_type(self): + return self.basicffitype + def descr_call(self, space, length, w_items=None, autofree=False): result = self.allocate(space, length, autofree) if not space.is_w(w_items, space.w_None): @@ -50,42 +59,28 @@ for num in range(iterlength): w_item = items_w[num] unwrap_value(space, push_elem, result.ll_buffer, num, - self.itemtp[0], w_item) + self.itemcode, w_item) return space.wrap(result) def descr_repr(self, space): - return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % self.itemtp) + return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % (self.itemcode, + self.size, + self.alignment)) descr_repr.unwrap_spec = ['self', ObjSpace] def fromaddress(self, space, address, length): return space.wrap(W_ArrayInstance(space, self, length, address)) fromaddress.unwrap_spec = ['self', ObjSpace, r_uint, int] - def _size_alignment(self): - _, itemsize, alignment = self.itemtp - return itemsize, alignment - -class ArrayCache: - def __init__(self, space): - self.space = space - self.cache = {} - self.array_of_ptr = self.get_array_type(letter2tp(space, 'P')) - - def get_array_type(self, itemtp): - try: - return self.cache[itemtp] - except KeyError: - result = W_Array(self.space, itemtp) - self.cache[itemtp] = result - return result - -def get_array_cache(space): - return space.fromcache(ArrayCache) +PRIMITIVE_ARRAY_TYPES = {} +for _code in TYPEMAP: + PRIMITIVE_ARRAY_TYPES[_code] = W_Array(TYPEMAP[_code], + size_alignment(TYPEMAP[_code])[0]) + PRIMITIVE_ARRAY_TYPES[_code].itemcode = _code +ARRAY_OF_PTRS = PRIMITIVE_ARRAY_TYPES['P'] def descr_new_array(space, w_type, w_shape): - itemtp = unpack_to_size_alignment(space, w_shape) - array_type = get_array_cache(space).get_array_type(itemtp) - return space.wrap(array_type) + return unpack_shape_with_length(space, w_shape) W_Array.typedef = TypeDef( 'Array', @@ -102,8 +97,7 @@ class W_ArrayInstance(W_DataInstance): def __init__(self, space, shape, length, address=r_uint(0)): - _, itemsize, _ = shape.itemtp - W_DataInstance.__init__(self, space, itemsize * length, address) + W_DataInstance.__init__(self, space, shape.size * length, address) self.length = length self.shape = shape @@ -122,7 +116,7 @@ if num >= self.length or num < 0: raise OperationError(space.w_IndexError, space.w_None) unwrap_value(space, push_elem, self.ll_buffer, num, - self.shape.itemtp[0], w_value) + self.shape.itemcode, w_value) def descr_setitem(self, space, w_index, w_value): try: @@ -141,7 +135,7 @@ if num >= self.length or num < 0: raise OperationError(space.w_IndexError, space.w_None) return wrap_value(space, get_elem, self.ll_buffer, num, - self.shape.itemtp) + self.shape.itemcode) def descr_getitem(self, space, w_index): try: @@ -159,20 +153,20 @@ getlength.unwrap_spec = ['self', ObjSpace] def descr_itemaddress(self, space, num): - _, itemsize, _ = self.shape.itemtp + itemsize = self.shape.size ptr = rffi.ptradd(self.ll_buffer, itemsize * num) return space.wrap(rffi.cast(lltype.Unsigned, ptr)) descr_itemaddress.unwrap_spec = ['self', ObjSpace, int] def getrawsize(self): - _, itemsize, _ = self.shape.itemtp + itemsize = self.shape.size return itemsize * self.length def decodeslice(self, space, w_slice): if not space.is_true(space.isinstance(w_slice, space.w_slice)): raise OperationError(space.w_TypeError, space.wrap('index must be int or slice')) - letter, _, _ = self.shape.itemtp + letter = self.shape.itemcode if letter != 'c': raise OperationError(space.w_TypeError, space.wrap("only 'c' arrays support slicing")) @@ -241,7 +235,7 @@ self._free() W_ArrayInstanceAutoFree.typedef = TypeDef( - 'ArrayInstanceWithFree', + 'ArrayInstanceAutoFree', __repr__ = interp2app(W_ArrayInstance.descr_repr), __setitem__ = interp2app(W_ArrayInstance.descr_setitem), __getitem__ = interp2app(W_ArrayInstance.descr_getitem), Modified: pypy/trunk/pypy/module/_rawffi/callback.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/callback.py (original) +++ pypy/trunk/pypy/module/_rawffi/callback.py Mon Mar 22 12:19:02 2010 @@ -6,9 +6,10 @@ from pypy.rpython.lltypesystem import lltype, rffi from pypy.module._rawffi.structure import unpack_fields from pypy.module._rawffi.array import get_elem, push_elem -from pypy.module._rawffi.interp_rawffi import W_DataInstance, _get_type_,\ - wrap_value, unwrap_value, unwrap_truncate_int, letter2tp +from pypy.module._rawffi.interp_rawffi import W_DataInstance, letter2tp, \ + wrap_value, unwrap_value, unwrap_truncate_int from pypy.rlib.libffi import USERDATA_P, CallbackFuncPtr, FUNCFLAG_CDECL +from pypy.rlib.libffi import ffi_type_void from pypy.module._rawffi.tracker import tracker from pypy.interpreter.error import OperationError from pypy.interpreter import gateway @@ -26,22 +27,24 @@ userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable - argtypes = callback_ptr.args + args = callback_ptr.args space = callback_ptr.space try: + # XXX The app-level callback gets the arguments as a list of integers. + # Irregular interface here. Shows something, I say. w_args = space.newlist([space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) - for i in range(len(argtypes))]) + for i in range(len(args))]) w_res = space.call(w_callable, w_args) - if callback_ptr.result != 'O': # don't return void + if callback_ptr.result is not None: # don't return void unwrap_value(space, push_elem, ll_res, 0, callback_ptr.result, w_res) except OperationError, e: tbprint(space, space.wrap(e.application_traceback), space.wrap(e.errorstr(space))) # force the result to be zero - if callback_ptr.result != 'O': - _, size, _ = letter2tp(space, callback_ptr.result) - for i in range(size): + if callback_ptr.result is not None: + resshape = letter2tp(space, callback_ptr.result) + for i in range(resshape.size): ll_res[i] = '\x00' # XXX some weird hackery to be able to recover W_CallbackPtr object @@ -58,18 +61,22 @@ def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): - number = global_counter.CallbackPtr_id - global_counter.CallbackPtr_id += 1 - global_counter.CallbackPtr_by_number[number] = self self.space = space self.w_callable = w_callable - self.number = number self.args = [space.str_w(w_arg) for w_arg in space.unpackiterable( w_args)] - self.result = space.str_w(w_result) - ffiargs = [_get_type_(space, arg) for arg in self.args] - ffiresult = _get_type_(space, self.result) + ffiargs = [letter2tp(space, x).get_basic_ffi_type() for x in self.args] + if not space.is_w(w_result, space.w_None): + self.result = space.str_w(w_result) + ffiresult = letter2tp(space, self.result).get_basic_ffi_type() + else: + self.result = None + ffiresult = ffi_type_void # necessary to keep stuff alive + number = global_counter.CallbackPtr_id + global_counter.CallbackPtr_id += 1 + global_counter.CallbackPtr_by_number[number] = self + self.number = number self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, number, flags) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.ll_closure) Modified: pypy/trunk/pypy/module/_rawffi/interp_rawffi.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/interp_rawffi.py (original) +++ pypy/trunk/pypy/module/_rawffi/interp_rawffi.py Mon Mar 22 12:19:02 2010 @@ -52,9 +52,6 @@ def size_alignment(ffi_type): return intmask(ffi_type.c_size), intmask(ffi_type.c_alignment) -UNPACKED_TYPECODES = dict([(code, (code,) + size_alignment(field_desc)) - for code, field_desc in TYPEMAP.items()]) - LL_TYPEMAP = { 'c' : rffi.CHAR, 'u' : lltype.UniChar, @@ -82,65 +79,56 @@ LL_TYPEMAP['v'] = rffi.SHORT def letter2tp(space, key): + from pypy.module._rawffi.array import PRIMITIVE_ARRAY_TYPES try: - return UNPACKED_TYPECODES[key] + return PRIMITIVE_ARRAY_TYPES[key] except KeyError: raise operationerrfmt(space.w_ValueError, "Unknown type letter %s", key) -def _get_type_(space, key): - try: - return TYPEMAP[key] - except KeyError: - raise operationerrfmt(space.w_ValueError, - "Unknown type letter %s", key) - -def unpack_to_ffi_type(space, w_shape, shape=False): - resshape = None +def unpack_simple_shape(space, w_shape): + # 'w_shape' must be either a letter or a tuple (struct, 1). if space.is_true(space.isinstance(w_shape, space.w_str)): letter = space.str_w(w_shape) - ffi_type = _get_type_(space, letter) - if shape: - from pypy.module._rawffi.array import get_array_cache - cache = get_array_cache(space) - resshape = cache.get_array_type(letter2tp(space, letter)) + return letter2tp(space, letter) else: - letter = 'V' w_shapetype, w_length = space.fixedview(w_shape, expected_length=2) from pypy.module._rawffi.structure import W_Structure - resshape = space.interp_w(W_Structure, w_shapetype) - ffi_type = resshape.get_ffi_type() - return letter, ffi_type, resshape + return space.interp_w(W_Structure, w_shapetype) -def unpack_to_size_alignment(space, w_shape): +def unpack_shape_with_length(space, w_shape): + # Allow 'w_shape' to be a letter or any (shape, number). + # The result is always a W_Array. if space.is_true(space.isinstance(w_shape, space.w_str)): letter = space.str_w(w_shape) return letter2tp(space, letter) else: w_shapetype, w_length = space.fixedview(w_shape, expected_length=2) - resshape = space.interp_w(W_DataShape, w_shapetype) length = space.int_w(w_length) - size, alignment = resshape._size_alignment() - return ('V', length*size, alignment) # value object + shape = space.interp_w(W_DataShape, w_shapetype) + if shape._array_shapes is None: + shape._array_shapes = {} + try: + result = shape._array_shapes[length] + except KeyError: + from pypy.module._rawffi.array import W_Array + if isinstance(shape, W_Array) and length == 1: + result = shape + else: + ffitype = shape.get_basic_ffi_type() + size = shape.size * length + result = W_Array(ffitype, size) + shape._array_shapes[length] = result + return result def unpack_resshape(space, w_restype): if space.is_w(w_restype, space.w_None): - resshape = None - ffi_restype = ffi_type_void - else: - tp_letter, ffi_restype, resshape = unpack_to_ffi_type(space, - w_restype, - shape=True) - return ffi_restype, resshape + return None + return unpack_simple_shape(space, w_restype) def unpack_argshapes(space, w_argtypes): - argletters = [] - ffi_argtypes = [] - for w_arg in space.unpackiterable(w_argtypes): - argletter, ffi_argtype, _ = unpack_to_ffi_type(space, w_arg) - argletters.append(argletter) - ffi_argtypes.append(ffi_argtype) - return ffi_argtypes, argletters + return [unpack_simple_shape(space, w_arg) + for w_arg in space.unpackiterable(w_argtypes)] class W_CDLL(Wrappable): def __init__(self, space, name): @@ -157,7 +145,7 @@ """ Get a pointer for function name with provided argtypes and restype """ - ffi_restype, resshape = unpack_resshape(space, w_restype) + resshape = unpack_resshape(space, w_restype) w = space.wrap argtypes_w = space.fixedview(w_argtypes) w_argtypes = space.newtuple(argtypes_w) @@ -169,7 +157,14 @@ pass else: raise - ffi_argtypes, argletters = unpack_argshapes(space, w_argtypes) + # Array arguments not supported directly (in C, an array argument + # will be just a pointer). And the result cannot be an array (at all). + argshapes = unpack_argshapes(space, w_argtypes) + ffi_argtypes = [shape.get_basic_ffi_type() for shape in argshapes] + if resshape is not None: + ffi_restype = resshape.get_basic_ffi_type() + else: + ffi_restype = ffi_type_void if space.is_true(space.isinstance(w_name, space.w_str)): name = space.str_w(w_name) @@ -194,7 +189,7 @@ raise OperationError(space.w_TypeError, space.wrap( "function name must be string or integer")) - w_funcptr = W_FuncPtr(space, ptr, argletters, resshape) + w_funcptr = W_FuncPtr(space, ptr, argshapes, resshape) space.setitem(self.w_cache, w_key, w_funcptr) return w_funcptr ptr.unwrap_spec = ['self', ObjSpace, W_Root, W_Root, W_Root, int] @@ -240,17 +235,20 @@ return OperationError(w_exception, space.wrap(reason)) class W_DataShape(Wrappable): - + _array_shapes = None + size = 0 + alignment = 0 + itemcode = '?' + def allocate(self, space, length, autofree=False): raise NotImplementedError - def _size_alignment(self): + def get_basic_ffi_type(self): raise NotImplementedError - + def descr_size_alignment(self, space, n=1): - size, alignment = self._size_alignment() - return space.newtuple([space.wrap(size * n), - space.wrap(alignment)]) + return space.newtuple([space.wrap(self.size * n), + space.wrap(self.alignment)]) descr_size_alignment.unwrap_spec = ['self', ObjSpace, int] @@ -269,9 +267,8 @@ return space.wrap(rffi.cast(lltype.Unsigned, self.ll_buffer)) def byptr(self, space): - from pypy.module._rawffi.array import get_array_cache - array_of_ptr = get_array_cache(space).array_of_ptr - array = array_of_ptr.allocate(space, 1) + from pypy.module._rawffi.array import ARRAY_OF_PTRS + array = ARRAY_OF_PTRS.allocate(space, 1) array.setitem(space, 0, space.wrap(self)) return space.wrap(array) byptr.unwrap_spec = ['self', ObjSpace] @@ -306,12 +303,7 @@ def unwrap_value(space, push_func, add_arg, argdesc, letter, w_arg): w = space.wrap - if letter == "d": - push_func(add_arg, argdesc, space.float_w(w_arg)) - elif letter == "f": - push_func(add_arg, argdesc, rffi.cast(rffi.FLOAT, - space.float_w(w_arg))) - elif letter in TYPEMAP_PTR_LETTERS: + if letter in TYPEMAP_PTR_LETTERS: # check for NULL ptr datainstance = space.interpclass_w(w_arg) if isinstance(datainstance, W_DataInstance): @@ -319,6 +311,11 @@ else: ptr = unwrap_truncate_int(rffi.VOIDP, space, w_arg) push_func(add_arg, argdesc, ptr) + elif letter == "d": + push_func(add_arg, argdesc, space.float_w(w_arg)) + elif letter == "f": + push_func(add_arg, argdesc, rffi.cast(rffi.FLOAT, + space.float_w(w_arg))) elif letter == "c": s = space.str_w(w_arg) if len(s) != 1: @@ -347,8 +344,7 @@ ll_typemap_iter = unrolling_iterable(LL_TYPEMAP.items()) -def wrap_value(space, func, add_arg, argdesc, tp): - letter, _, _ = tp +def wrap_value(space, func, add_arg, argdesc, letter): for c, ll_type in ll_typemap_iter: if letter == c: if c in TYPEMAP_PTR_LETTERS: @@ -365,9 +361,9 @@ wrap_value._annspecialcase_ = 'specialize:arg(1)' class W_FuncPtr(Wrappable): - def __init__(self, space, ptr, argletters, resshape): + def __init__(self, space, ptr, argshapes, resshape): self.ptr = ptr - self.argletters = argletters + self.argshapes = argshapes self.resshape = resshape def getbuffer(space, self): @@ -379,9 +375,8 @@ return space.wrap(rffi.cast(lltype.Unsigned, self.ptr.funcsym)) def byptr(self, space): - from pypy.module._rawffi.array import get_array_cache - array_of_ptr = get_array_cache(space).array_of_ptr - array = array_of_ptr.allocate(space, 1) + from pypy.module._rawffi.array import ARRAY_OF_PTRS + array = ARRAY_OF_PTRS.allocate(space, 1) array.setitem(space, 0, self._getbuffer(space)) if tracker.DO_TRACING: # XXX this is needed, because functions tend to live forever @@ -393,16 +388,17 @@ def call(self, space, args_w): from pypy.module._rawffi.array import W_ArrayInstance from pypy.module._rawffi.structure import W_StructureInstance + from pypy.module._rawffi.structure import W_Structure argnum = len(args_w) - if argnum != len(self.argletters): + if argnum != len(self.argshapes): msg = "Wrong number of arguments: expected %d, got %d" raise operationerrfmt(space.w_TypeError, msg, - len(self.argletters), argnum) + len(self.argshapes), argnum) args_ll = [] for i in range(argnum): - argletter = self.argletters[i] + argshape = self.argshapes[i] w_arg = args_w[i] - if argletter == 'V': # by value object + if isinstance(argshape, W_Structure): # argument by value arg = space.interp_w(W_StructureInstance, w_arg) xsize, xalignment = size_alignment(self.ptr.argtypes[i]) if (arg.shape.size != xsize or @@ -420,7 +416,8 @@ "got length %d") raise operationerrfmt(space.w_TypeError, msg, i+1, arg.length) - letter = arg.shape.itemtp[0] + argletter = argshape.itemcode + letter = arg.shape.itemcode if letter != argletter: if not (argletter in TYPEMAP_PTR_LETTERS and letter in TYPEMAP_PTR_LETTERS): @@ -443,11 +440,13 @@ call.unwrap_spec = ['self', ObjSpace, 'args_w'] def descr_new_funcptr(space, w_tp, addr, w_args, w_res, flags=FUNCFLAG_CDECL): - ffi_args, args = unpack_argshapes(space, w_args) - ffi_res, res = unpack_resshape(space, w_res) + argshapes = unpack_argshapes(space, w_args) + resshape = unpack_resshape(space, w_res) + ffi_args = [shape.get_basic_ffi_type() for shape in argshapes] + ffi_res = resshape.get_basic_ffi_type() ptr = RawFuncPtr('???', ffi_args, ffi_res, rffi.cast(rffi.VOIDP, addr), flags) - return space.wrap(W_FuncPtr(space, ptr, args, res)) + return space.wrap(W_FuncPtr(space, ptr, argshapes, resshape)) descr_new_funcptr.unwrap_spec = [ObjSpace, W_Root, r_uint, W_Root, W_Root, int] W_FuncPtr.typedef = TypeDef( Modified: pypy/trunk/pypy/module/_rawffi/structure.py ============================================================================== --- pypy/trunk/pypy/module/_rawffi/structure.py (original) +++ pypy/trunk/pypy/module/_rawffi/structure.py Mon Mar 22 12:19:02 2010 @@ -13,7 +13,8 @@ from pypy.module._rawffi.interp_rawffi import segfault_exception from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value -from pypy.module._rawffi.interp_rawffi import unpack_to_size_alignment +from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length +from pypy.module._rawffi.interp_rawffi import size_alignment from pypy.rlib import libffi from pypy.rlib.rarithmetic import intmask, r_uint @@ -26,7 +27,7 @@ raise OperationError(space.w_ValueError, space.wrap( "Expected list of 2-size tuples")) name = space.str_w(l_w[0]) - tp = unpack_to_size_alignment(space, l_w[1]) + tp = unpack_shape_with_length(space, l_w[1]) fields.append((name, tp)) return fields @@ -37,7 +38,10 @@ size = 0 alignment = 1 pos = [] - for fieldname, (letter, fieldsize, fieldalignment) in fields: + for fieldname, fieldtype in fields: + # fieldtype is a W_Array + fieldsize = fieldtype.size + fieldalignment = fieldtype.alignment size = round_up(size, fieldalignment) alignment = max(alignment, fieldalignment) pos.append(size) @@ -99,21 +103,33 @@ return space.wrap(self.ll_positions[index]) descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str] - def _size_alignment(self): - return self.size, self.alignment - # get the corresponding ffi_type - ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO) + ffi_struct = lltype.nullptr(libffi.FFI_STRUCT_P.TO) - def get_ffi_type(self): - if not self.ffi_type: - self.ffi_type = libffi.make_struct_ffitype(self.size, - self.alignment) - return self.ffi_type + def get_basic_ffi_type(self): + if not self.ffi_struct: + # Repeated fields are delicate. Consider for example + # struct { int a[5]; } + # or struct { struct {int x;} a[5]; } + # Seeing no corresponding doc in libffi, let's just repeat + # the field 5 times... + fieldtypes = [] + for name, tp in self.fields: + basic_ffi_type = tp.get_basic_ffi_type() + basic_size, _ = size_alignment(basic_ffi_type) + total_size = tp.size + count = 0 + while count + basic_size <= total_size: + fieldtypes.append(basic_ffi_type) + count += basic_size + self.ffi_struct = libffi.make_struct_ffitype_e(self.size, + self.alignment, + fieldtypes) + return self.ffi_struct.ffistruct def __del__(self): - if self.ffi_type: - lltype.free(self.ffi_type, flavor='raw') + if self.ffi_struct: + lltype.free(self.ffi_struct, flavor='raw') @@ -168,7 +184,7 @@ raise segfault_exception(space, "accessing NULL pointer") i = self.shape.getindex(space, attr) _, tp = self.shape.fields[i] - return wrap_value(space, cast_pos, self, i, tp) + return wrap_value(space, cast_pos, self, i, tp.itemcode) getattr.unwrap_spec = ['self', ObjSpace, str] def setattr(self, space, attr, w_value): @@ -176,7 +192,7 @@ raise segfault_exception(space, "accessing NULL pointer") i = self.shape.getindex(space, attr) _, tp = self.shape.fields[i] - unwrap_value(space, push_field, self, i, tp[0], w_value) + unwrap_value(space, push_field, self, i, tp.itemcode, w_value) setattr.unwrap_spec = ['self', ObjSpace, str, W_Root] def descr_fieldaddress(self, space, attr): 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 Mon Mar 22 12:19:02 2010 @@ -141,6 +141,21 @@ return inp; } + struct s2a { + int bah[2]; + }; + + struct s2a get_s2a(void) { + struct s2a outp; + outp.bah[0] = 4; + outp.bah[1] = 5; + return outp; + } + + int check_s2a(struct s2a inp) { + return (inp.bah[0] == 4 && inp.bah[1] == 5); + } + int AAA_first_ordinal_function() { return 42; @@ -157,7 +172,7 @@ allocate_array static_int static_double sum_x_y - give perturb + give perturb get_s2a check_s2a AAA_first_ordinal_function """.split() eci = ExternalCompilationInfo(export_symbols=symbols) @@ -178,9 +193,6 @@ cls.w_libm_name = space.wrap('libm.so') if sys.platform == "darwin": cls.w_libm_name = space.wrap('libm.dylib') - import platform - cls.w_isx86_64 = space.wrap(platform.machine() == 'x86_64') - cls.w_sizes_and_alignments = space.wrap(dict( [(k, (v.c_size, v.c_alignment)) for k,v in TYPEMAP.iteritems()])) @@ -538,6 +550,22 @@ a1.free() del cb + def test_void_returning_callback(self): + import _rawffi + lib = _rawffi.CDLL(self.lib_name) + runcallback = lib.ptr('runcallback', ['P'], None) + called = [] + def callback(): + called.append(True) + + cb = _rawffi.CallbackPtr(callback, [], None) + a1 = cb.byptr() + res = runcallback(a1) + assert res is None + assert called == [True] + a1.free() + del cb + def test_another_callback_in_stackless(self): try: import _stackless @@ -665,7 +693,7 @@ # fragile S = _rawffi.Structure([('x', 'c'), ('y', 'l')]) assert (repr(_rawffi.Array((S, 2))) == - "<_rawffi.Array 'V' (%d, %d)>" % (4*lsize, lsize)) + "<_rawffi.Array '?' (%d, %d)>" % (4*lsize, lsize)) assert (repr(_rawffi.Structure([('x', 'i'), ('yz', 'i')])) == "<_rawffi.Structure 'x' 'yz' (%d, %d)>" % (2*isize, isize)) @@ -819,28 +847,21 @@ assert 0, "Did not raise" def test_struct_byvalue(self): - if self.isx86_64: - skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") - - import _rawffi + import _rawffi, sys X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')]) x_y = X_Y() lib = _rawffi.CDLL(self.lib_name) + print >> sys.stderr, "getting..." sum_x_y = lib.ptr('sum_x_y', [(X_Y, 1)], 'l') x_y.x = 200 x_y.y = 220 + print >> sys.stderr, "calling..." res = sum_x_y(x_y) + print >> sys.stderr, "done" assert res[0] == 420 x_y.free() def test_ret_struct(self): - if self.isx86_64: - skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") - import _rawffi S2H = _rawffi.Structure([('x', 'h'), ('y', 'h')]) s2h = S2H() @@ -871,6 +892,20 @@ s2h.free() + def test_ret_struct_containing_array(self): + import _rawffi + AoI = _rawffi.Array('i') + S2A = _rawffi.Structure([('bah', (AoI, 2))]) + lib = _rawffi.CDLL(self.lib_name) + get_s2a = lib.ptr('get_s2a', [], (S2A, 1)) + check_s2a = lib.ptr('check_s2a', [(S2A, 1)], 'i') + + res = get_s2a() + assert isinstance(res, _rawffi.StructureInstanceAutoFree) + assert res.shape is S2A + ok = check_s2a(res) + assert ok[0] == 1 + def test_buffer(self): import _rawffi S = _rawffi.Structure((40, 1)) Modified: pypy/trunk/pypy/rlib/libffi.py ============================================================================== --- pypy/trunk/pypy/rlib/libffi.py (original) +++ pypy/trunk/pypy/rlib/libffi.py Mon Mar 22 12:19:02 2010 @@ -366,13 +366,26 @@ CALLBACK_TP, rffi.VOIDP], rffi.INT) -def make_struct_ffitype(size, aligment): - tp = lltype.malloc(FFI_TYPE_P.TO, flavor='raw') - tp.c_type = FFI_TYPE_STRUCT - tp.c_size = rffi.cast(rffi.SIZE_T, size) - tp.c_alignment = rffi.cast(rffi.USHORT, aligment) - tp.c_elements = lltype.nullptr(FFI_TYPE_PP.TO) - return tp +FFI_STRUCT_P = lltype.Ptr(lltype.Struct('FFI_STRUCT', + ('ffistruct', FFI_TYPE_P.TO), + ('members', lltype.Array(FFI_TYPE_P)))) + +def make_struct_ffitype_e(size, aligment, field_types): + """Compute the type of a structure. Returns a FFI_STRUCT_P out of + which the 'ffistruct' member is a regular FFI_TYPE. + """ + tpe = lltype.malloc(FFI_STRUCT_P.TO, len(field_types)+1, flavor='raw') + tpe.ffistruct.c_type = FFI_TYPE_STRUCT + tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size) + tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment) + tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP, + lltype.direct_arrayitems(tpe.members)) + n = 0 + while n < len(field_types): + tpe.members[n] = field_types[n] + n += 1 + tpe.members[n] = lltype.nullptr(FFI_TYPE_P.TO) + return tpe def cast_type_to_ffitype(tp): """ This function returns ffi representation of rpython type tp 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 Mon Mar 22 12:19:02 2010 @@ -233,19 +233,27 @@ del libm assert not ALLOCATED - def test_make_struct_fftiype(self): - tp = make_struct_ffitype(6, 2) - assert tp.c_type == FFI_TYPE_STRUCT - assert tp.c_size == 6 - assert tp.c_alignment == 2 - lltype.free(tp, flavor='raw') + def test_make_struct_ffitype_e(self): + tpe = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar]) + assert tpe.ffistruct.c_type == FFI_TYPE_STRUCT + assert tpe.ffistruct.c_size == 16 + assert tpe.ffistruct.c_alignment == 4 + assert tpe.ffistruct.c_elements[0] == ffi_type_pointer + assert tpe.ffistruct.c_elements[1] == ffi_type_uchar + assert not tpe.ffistruct.c_elements[2] + lltype.free(tpe, flavor='raw') + + def test_nested_struct_elements(self): + tpe2 = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar]) + tp2 = tpe2.ffistruct + tpe = make_struct_ffitype_e(32, 4, [tp2, ffi_type_schar]) + assert tpe.ffistruct.c_elements[0] == tp2 + assert tpe.ffistruct.c_elements[1] == ffi_type_schar + assert not tpe.ffistruct.c_elements[2] + lltype.free(tpe, flavor='raw') + lltype.free(tpe2, flavor='raw') def test_struct_by_val(self): - import platform - if platform.machine() == 'x86_64': - py.test.skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import platform from pypy.tool.udir import udir @@ -277,9 +285,9 @@ slong = cast_type_to_ffitype(rffi.LONG) size = slong.c_size*2 alignment = slong.c_alignment - tp = make_struct_ffitype(size, alignment) + tpe = make_struct_ffitype_e(size, alignment, [slong, slong]) - sum_x_y = lib.getrawpointer('sum_x_y', [tp], slong) + sum_x_y = lib.getrawpointer('sum_x_y', [tpe.ffistruct], slong) buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw') buffer[0] = 200 @@ -291,17 +299,12 @@ lltype.free(buffer, flavor='raw') del sum_x_y - lltype.free(tp, flavor='raw') + lltype.free(tpe, flavor='raw') del lib assert not ALLOCATED def test_ret_struct_val(self): - import platform - if platform.machine() == 'x86_64': - py.test.skip("Segfaults on x86_64 because small structures " - "may be passed in registers and " - "c_elements must not be null") from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.translator.platform import platform from pypy.tool.udir import udir @@ -337,10 +340,10 @@ size = ffi_type_sshort.c_size*2 alignment = ffi_type_sshort.c_alignment - tp = make_struct_ffitype(size, alignment) + tpe = make_struct_ffitype_e(size, alignment, [ffi_type_sshort]*2) give = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort], - tp) + tpe.ffistruct) inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw') inbuffer[0] = rffi.cast(rffi.SHORT, 40) inbuffer[1] = rffi.cast(rffi.SHORT, 72) @@ -354,7 +357,7 @@ assert outbuffer[0] == 40 assert outbuffer[1] == 72 - perturb = lib.getrawpointer('perturb', [tp], tp) + perturb = lib.getrawpointer('perturb', [tpe.ffistruct], tpe.ffistruct) inbuffer[0] = rffi.cast(rffi.SHORT, 7) inbuffer[1] = rffi.cast(rffi.SHORT, 11) @@ -372,7 +375,7 @@ lltype.free(inbuffer, flavor='raw') del give del perturb - lltype.free(tp, flavor='raw') + lltype.free(tpe, flavor='raw') del lib assert not ALLOCATED From arigo at codespeak.net Mon Mar 22 12:19:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:19:20 +0100 (CET) Subject: [pypy-svn] r72533 - pypy/branch/rawffi-64 Message-ID: <20100322111920.229A7282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:19:18 2010 New Revision: 72533 Removed: pypy/branch/rawffi-64/ Log: Remove merged branch. From arigo at codespeak.net Mon Mar 22 12:32:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:32:30 +0100 (CET) Subject: [pypy-svn] r72534 - pypy/trunk/py/impl/test Message-ID: <20100322113230.57FD9282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:32:28 2010 New Revision: 72534 Modified: pypy/trunk/py/impl/test/outcome.py Log: Another fix in the py lib. I don't like too much checking in there, but it really obscures a test failure... Modified: pypy/trunk/py/impl/test/outcome.py ============================================================================== --- pypy/trunk/py/impl/test/outcome.py (original) +++ pypy/trunk/py/impl/test/outcome.py Mon Mar 22 12:32:28 2010 @@ -90,7 +90,7 @@ k = ", ".join(["%s=%r" % x for x in kwargs.items()]) if k: k = ', ' + k - expr = '%s(%r%s)' %(func.__name__, args, k) + expr = '%s(%r%s)' %(getattr(func, '__name__', func), args, k) raise ExceptionFailure(msg="DID NOT RAISE", expr=args, expected=ExpectedException) From arigo at codespeak.net Mon Mar 22 12:37:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:37:57 +0100 (CET) Subject: [pypy-svn] r72535 - pypy/trunk/pypy/translator/c/test Message-ID: <20100322113757.62524282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:37:55 2010 New Revision: 72535 Modified: pypy/trunk/pypy/translator/c/test/test_typed.py Log: Fix tests. 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 Mon Mar 22 12:37:55 2010 @@ -242,12 +242,12 @@ def f(i): return 4*i fn = self.getcompiled(f, [r_ulonglong], view=False) - assert fn(sys.maxint) == 4*sys.maxint + assert fn(2147483647) == 4*2147483647 def g(i): return 4*i gn = self.getcompiled(g, [r_longlong], view=False) - assert gn(sys.maxint) == 4*sys.maxint + assert gn(2147483647) == 4*2147483647 def test_specializing_int_functions(self): def f(i): From arigo at codespeak.net Mon Mar 22 12:38:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:38:24 +0100 (CET) Subject: [pypy-svn] r72536 - pypy/trunk/pypy/translator/c/src Message-ID: <20100322113824.67C68282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:38:22 2010 New Revision: 72536 Modified: pypy/trunk/pypy/translator/c/src/int.h Log: Can a C compiler be too clever and think it can "prove" that r >= x always holds here? Yes. Hence the casting. Modified: pypy/trunk/pypy/translator/c/src/int.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/int.h (original) +++ pypy/trunk/pypy/translator/c/src/int.h Mon Mar 22 12:38:22 2010 @@ -57,11 +57,11 @@ else FAIL_OVF("integer addition") #define OP_INT_ADD_NONNEG_OVF(x,y,r) /* y can be assumed >= 0 */ \ - OP_INT_ADD(x,y,r); \ + r = (long)((unsigned long)x + (unsigned long)y); \ if (r >= (x)); \ else FAIL_OVF("integer addition") -/* XXX can a C compiler be too clever and think it can "prove" that - * r >= x always hold above? */ +/* Can a C compiler be too clever and think it can "prove" that + * r >= x always holds above? Yes. Hence the casting. */ #define OP_INT_SUB(x,y,r) r = (x) - (y) From arigo at codespeak.net Mon Mar 22 12:43:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:43:36 +0100 (CET) Subject: [pypy-svn] r72537 - pypy/trunk/pypy/translator/c/gcc/test Message-ID: <20100322114336.5AA3F282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:43:34 2010 New Revision: 72537 Added: pypy/trunk/pypy/translator/c/gcc/test/conftest.py - copied unchanged from r72511, pypy/trunk/pypy/jit/backend/x86/test/conftest.py Log: Add a conftest to skip this directory if we are not on Intel 32-bit. From arigo at codespeak.net Mon Mar 22 12:51:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 12:51:15 +0100 (CET) Subject: [pypy-svn] r72539 - pypy/trunk/pypy/translator/backendopt/test Message-ID: <20100322115115.AFCA9282B90@codespeak.net> Author: arigo Date: Mon Mar 22 12:51:14 2010 New Revision: 72539 Modified: pypy/trunk/pypy/translator/backendopt/test/test_merge_if_blocks.py Log: Fix test for 64-bit. Modified: pypy/trunk/pypy/translator/backendopt/test/test_merge_if_blocks.py ============================================================================== --- pypy/trunk/pypy/translator/backendopt/test/test_merge_if_blocks.py (original) +++ pypy/trunk/pypy/translator/backendopt/test/test_merge_if_blocks.py Mon Mar 22 12:51:14 2010 @@ -5,7 +5,7 @@ from pypy.objspace.flow.model import flatten, Block from pypy.translator.backendopt.removenoops import remove_same_as from pypy.rpython.llinterp import LLInterpreter -from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong +from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, r_int from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint def do_test_merge(fn, testvalues): @@ -38,7 +38,8 @@ return 4 do_test_merge(merge_int, range(4)) do_test_merge(merge_int, [r_uint(i) for i in range(4)]) - do_test_merge(merge_int, [r_longlong(i) for i in range(4)]) + if r_longlong is not r_int: + do_test_merge(merge_int, [r_longlong(i) for i in range(4)]) do_test_merge(merge_int, [r_ulonglong(i) for i in range(4)]) def merge_chr(n): From arigo at codespeak.net Mon Mar 22 13:14:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 13:14:09 +0100 (CET) Subject: [pypy-svn] r72540 - pypy/build/bot2/pypybuildbot Message-ID: <20100322121409.4186E282B90@codespeak.net> Author: arigo Date: Mon Mar 22 13:14:06 2010 New Revision: 72540 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Rename 'tannit' into 'tannit32', and add 'tannit64'. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Mon Mar 22 13:14:06 2010 @@ -109,6 +109,7 @@ pypyJITBenchmarkFactory = pypybuilds.JITBenchmark() LINUX32 = "own-linux-x86-32" +LINUX64 = "own-linux-x86-64" MACOSX32 = "own-macosx-x86-32" APPLVLLINUX32 = "pypy-c-app-level-linux-x86-32" STACKLESSAPPLVLLINUX32 = "pypy-c-stackless-app-level-linux-x86-32" @@ -146,11 +147,17 @@ 'builders': [ {"name": LINUX32, - "slavenames": ["cobra", "bigdogvm1", "tannit"], + "slavenames": ["cobra", "bigdogvm1", "tannit32"], "builddir": LINUX32, "factory": pypyOwnTestFactory, "category": 'own' }, + {"name": LINUX64, + "slavenames": ["tannit64"], + "builddir": LINUX64, + "factory": pypyOwnTestFactory, + "category": 'own' + }, {"name": MACOSX32, "slavenames": ["minime"], "builddir": MACOSX32, @@ -158,19 +165,19 @@ "category": 'mac' }, {"name": APPLVLLINUX32, - "slavenames": ["bigdogvm1", "tannit"], + "slavenames": ["bigdogvm1", "tannit32"], "builddir": APPLVLLINUX32, "factory": pypyTranslatedAppLevelTestFactory, 'category': 'applevel' }, {"name": STACKLESSAPPLVLLINUX32, - "slavenames": ["bigdogvm1", "tannit"], + "slavenames": ["bigdogvm1", "tannit32"], "builddir": STACKLESSAPPLVLLINUX32, "factory": pypyStacklessTranslatedAppLevelTestFactory, "category": 'stackless' }, {"name": OJITLINUX32, - "slavenames": ["bigdogvm1", "tannit"], + "slavenames": ["bigdogvm1", "tannit32"], "builddir": OJITLINUX32, "factory": pypy_OjitTranslatedTestFactory, "category": 'applevel' @@ -188,7 +195,7 @@ "category": 'other' }, {"name" : JITLINUX32, - "slavenames": ["bigdogvm1", "tannit"], + "slavenames": ["bigdogvm1", "tannit32"], 'builddir' : JITLINUX32, 'factory' : pypyJITTranslatedTestFactory, 'category' : 'jit', @@ -206,7 +213,7 @@ 'category' : 'jit', }, {"name": JITONLYLINUX32, - "slavenames": ["tannit", "bigdogvm1"], + "slavenames": ["tannit32", "bigdogvm1"], "builddir": JITONLYLINUX32, "factory": pypyJitOnlyOwnTestFactory, "category": 'own' From arigo at codespeak.net Mon Mar 22 13:36:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 13:36:42 +0100 (CET) Subject: [pypy-svn] r72541 - pypy/build/testrunner Message-ID: <20100322123642.76E2A282B90@codespeak.net> Author: arigo Date: Mon Mar 22 13:36:41 2010 New Revision: 72541 Modified: pypy/build/testrunner/runner.py Log: Increase the polling frequency to keep the machines busy. Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Mon Mar 22 13:36:41 2010 @@ -69,7 +69,7 @@ else: timedout = TIMEDOUT _kill(p.pid, SIGTERM) - time.sleep(min(timeout, 10)) + time.sleep(3) finally: f.close() From jandem at codespeak.net Mon Mar 22 13:38:39 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Mon, 22 Mar 2010 13:38:39 +0100 (CET) Subject: [pypy-svn] r72542 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100322123839.23407282B90@codespeak.net> Author: jandem Date: Mon Mar 22 13:38:37 2010 New Revision: 72542 Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Log: Add PyString_Size Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Mon Mar 22 13:38:37 2010 @@ -19,9 +19,21 @@ { return PyString_FromString("Hello world"); } + static PyObject* foo_test_Size(PyObject* self, PyObject *args) + { + PyObject* s = PyString_FromString("Hello world"); + int result = 0; + + if(PyString_Size(s) == 11) { + result = 1; + } + Py_DECREF(s); + return PyBool_FromLong(result); + } static PyMethodDef methods[] = { { "get_hello1", foo_get_hello1, METH_NOARGS }, { "get_hello2", foo_get_hello2, METH_NOARGS }, + { "test_Size", foo_test_Size, METH_NOARGS }, { NULL } }; """ @@ -29,3 +41,4 @@ assert 'foo' in sys.modules assert module.get_hello1() == 'Hello world' assert module.get_hello2() == 'Hello world' + assert module.test_Size() From afa at codespeak.net Mon Mar 22 13:39:52 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 13:39:52 +0100 (CET) Subject: [pypy-svn] r72543 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100322123952.20F3E282B90@codespeak.net> Author: afa Date: Mon Mar 22 13:39:50 2010 New Revision: 72543 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/object.h pypy/trunk/pypy/module/cpyext/typeobject.py Log: Add a way to declare api functions implemented in C. this allows the dll to export them correctly, and fixes tests on Windows. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 13:39:50 2010 @@ -62,6 +62,11 @@ return func return decorate +def cpython_api_c(): + def decorate(func): + FUNCTIONS_C[func.func_name] = None + return decorate + def cpython_struct(name, fields, forward=None): configname = name.replace(' ', '__') setattr(CConfig, configname, rffi_platform.Struct(name, fields)) @@ -71,6 +76,7 @@ return forward FUNCTIONS = {} +FUNCTIONS_C = {} TYPES = {} GLOBALS = { 'Py_None': ('PyObject*', 'space.w_None'), @@ -179,7 +185,7 @@ def build_bridge(space, rename=True): db = LowLevelDatabase() - export_symbols = list(FUNCTIONS) + list(GLOBALS) + export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) structindex = {} Modified: pypy/trunk/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/object.h (original) +++ pypy/trunk/pypy/module/cpyext/include/object.h Mon Mar 22 13:39:50 2010 @@ -377,8 +377,7 @@ PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; -int PyPyType_Ready(PyTypeObject *); -#define PyType_Ready PyPyType_Ready +int PyType_Ready(PyTypeObject *); /* objimpl.h ----------------------------------------------*/ Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Mon Mar 22 13:39:50 2010 @@ -8,8 +8,9 @@ from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, Py_TPFLAGS_READY +from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct +from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t +from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State @@ -171,6 +172,9 @@ w_type.ready() return w_type + at cpython_api_c() +def PyType_Ready(space, pto): + "Implemented in typeobject.c" @cpython_api([PyTypeObjectPtr], rffi.INT_real) def PyPyType_Register(space, pto): From afa at codespeak.net Mon Mar 22 13:54:25 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 13:54:25 +0100 (CET) Subject: [pypy-svn] r72544 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100322125425.5A2E6282B90@codespeak.net> Author: afa Date: Mon Mar 22 13:54:23 2010 New Revision: 72544 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/include/Python.h Log: Let the configure() work Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 13:54:23 2010 @@ -14,6 +14,7 @@ from pypy.translator import platform from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import ObjSpace, unwrap_spec Py_ssize_t = lltype.Signed @@ -33,17 +34,13 @@ class CConfig_constants: _compilation_info_ = CConfig._compilation_info_ -constant_names = """Py_TPFLAGS_READY Py_TPFLAGS_READYING """.split() +constant_names = """ +Py_TPFLAGS_READY Py_TPFLAGS_READYING +METH_COEXIST METH_STATIC METH_CLASS METH_NOARGS +""".split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) -# XXX does not work, why? -#globals().update(rffi_platform.configure(CConfig_constants)) -Py_TPFLAGS_READY = (1L<<12) -Py_TPFLAGS_READYING = (1L<<13) -METH_COEXIST = 0x0040 -METH_STATIC = 0x0020 -METH_CLASS = 0x0010 -METH_NOARGS = 0x0004 +globals().update(rffi_platform.configure(CConfig_constants)) class ApiFunction: @@ -191,6 +188,7 @@ prologue = """\ #define const /* cheat */ + #include #include """ pypy_rename = [] Modified: pypy/trunk/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/Python.h (original) +++ pypy/trunk/pypy/module/cpyext/include/Python.h Mon Mar 22 13:54:23 2010 @@ -1,7 +1,6 @@ #ifndef Py_PYTHON_H #define Py_PYTHON_H -#include /* Compat stuff */ #ifndef _WIN32 # include From jandem at codespeak.net Mon Mar 22 14:22:14 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Mon, 22 Mar 2010 14:22:14 +0100 (CET) Subject: [pypy-svn] r72548 - in pypy/trunk/pypy/module/cpyext: . include Message-ID: <20100322132214.3A290282B90@codespeak.net> Author: jandem Date: Mon Mar 22 14:22:12 2010 New Revision: 72548 Modified: pypy/trunk/pypy/module/cpyext/include/stringobject.h pypy/trunk/pypy/module/cpyext/stringobject.py Log: Add PyString_Size Modified: pypy/trunk/pypy/module/cpyext/include/stringobject.h ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/stringobject.h (original) +++ pypy/trunk/pypy/module/cpyext/include/stringobject.h Mon Mar 22 14:22:12 2010 @@ -9,6 +9,7 @@ PyObject * PyString_FromStringAndSize(const char *, Py_ssize_t); PyObject * PyString_FromString(const char *); +Py_ssize_t PyString_Size(PyObject *); #ifdef __cplusplus } Modified: pypy/trunk/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/stringobject.py Mon Mar 22 14:22:12 2010 @@ -15,3 +15,7 @@ def PyString_FromString(space, char_p): s = rffi.charp2str(char_p) return space.wrap(s) + + at cpython_api([PyObject], Py_ssize_t) +def PyString_Size(space, w_obj): + return space.int_w(space.len(w_obj)) From jandem at codespeak.net Mon Mar 22 14:37:01 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Mon, 22 Mar 2010 14:37:01 +0100 (CET) Subject: [pypy-svn] r72550 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100322133701.11185282B90@codespeak.net> Author: jandem Date: Mon Mar 22 14:36:59 2010 New Revision: 72550 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Log: Test that PyString_Size correctly handles exceptions and fix a small bug in the exception handling code Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 14:36:59 2010 @@ -307,8 +307,10 @@ return if restype is PyObject: return lltype.nullptr(PyObject.TO) - if restype in (lltype.Signed, rffi.INT_real): - return rffi.cast(rffi.INT_real, -1) + if restype is lltype.Signed: + return rffi.cast(lltype.Signed, -1) + if restype is rffi.INT_REAL: + return rffi.cast(rffi.INT_REAL, -1) assert False, "Unknown return type" if callable.api_func.restype is PyObject: Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Mon Mar 22 14:36:59 2010 @@ -30,10 +30,19 @@ Py_DECREF(s); return PyBool_FromLong(result); } + static PyObject* foo_test_Size_exception(PyObject* self, PyObject *args) + { + PyObject* f = PyFloat_FromDouble(1.0); + Py_ssize_t size = PyString_Size(f); + + Py_DECREF(f); + return NULL; + } static PyMethodDef methods[] = { { "get_hello1", foo_get_hello1, METH_NOARGS }, { "get_hello2", foo_get_hello2, METH_NOARGS }, { "test_Size", foo_test_Size, METH_NOARGS }, + { "test_Size_exception", foo_test_Size_exception, METH_NOARGS }, { NULL } }; """ @@ -42,3 +51,4 @@ assert module.get_hello1() == 'Hello world' assert module.get_hello2() == 'Hello world' assert module.test_Size() + raises(TypeError, "module.test_Size_exception()") From afa at codespeak.net Mon Mar 22 14:43:38 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 14:43:38 +0100 (CET) Subject: [pypy-svn] r72553 - pypy/trunk/pypy/module/cpyext/test Message-ID: <20100322134338.3C469282B90@codespeak.net> Author: afa Date: Mon Mar 22 14:43:36 2010 New Revision: 72553 Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Log: Slightly better interface for building extension, it focuses on the function content, not the declarations. Modified: pypy/trunk/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_cpyext.py Mon Mar 22 14:43:36 2010 @@ -79,8 +79,34 @@ self.space.sys.get('modules'), self.space.wrap(name)) + def import_extension(self, modname, functions): + + methods_table = [] + codes = [] + for funcname, flags, code in functions: + cfuncname = "%s_%s" % (modname, funcname) + methods_table.append("{\"%s\", %s, %s}," % + (funcname, cfuncname, flags)) + func_code = """ + static PyObject* %s(PyObject* self, PyObject* args) + { + %s + } + """ % (cfuncname, code) + codes.append(func_code) + + body = "\n".join(codes) + """ + static PyMethodDef methods[] = { + %s + { NULL } + }; + """ % ('\n'.join(methods_table),) + init = """Py_InitModule("%s", methods);""" % (modname,) + return self.import_module(name=modname, init=init, body=body) + def setup_method(self, func): self.w_import_module = self.space.wrap(self.import_module) + self.w_import_extension = self.space.wrap(self.import_extension) self.w_check_refcnts = self.space.wrap(self.check_refcnts) #self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!") #self.space.fromcache(State).print_refcounts() Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Mon Mar 22 14:43:36 2010 @@ -5,49 +5,36 @@ class AppTestStringObject(AppTestCpythonExtensionBase): def test_stringobject(self): - import sys - init = """ - if (Py_IsInitialized()) - Py_InitModule("foo", methods); - """ - body = """ - static PyObject* foo_get_hello1(PyObject* self, PyObject *args) - { - return PyString_FromStringAndSize("Hello world", 11); - } - static PyObject* foo_get_hello2(PyObject* self, PyObject *args) - { - return PyString_FromString("Hello world"); - } - static PyObject* foo_test_Size(PyObject* self, PyObject *args) - { - PyObject* s = PyString_FromString("Hello world"); - int result = 0; - - if(PyString_Size(s) == 11) { - result = 1; - } - Py_DECREF(s); - return PyBool_FromLong(result); - } - static PyObject* foo_test_Size_exception(PyObject* self, PyObject *args) - { - PyObject* f = PyFloat_FromDouble(1.0); - Py_ssize_t size = PyString_Size(f); - - Py_DECREF(f); - return NULL; - } - static PyMethodDef methods[] = { - { "get_hello1", foo_get_hello1, METH_NOARGS }, - { "get_hello2", foo_get_hello2, METH_NOARGS }, - { "test_Size", foo_test_Size, METH_NOARGS }, - { "test_Size_exception", foo_test_Size_exception, METH_NOARGS }, - { NULL } - }; - """ - module = self.import_module(name='foo', init=init, body=body) - assert 'foo' in sys.modules + module = self.import_extension('foo', [ + ("get_hello1", "METH_NOARGS", + """ + return PyString_FromStringAndSize( + "Hello world", 11); + """), + ("get_hello2", "METH_NOARGS", + """ + return PyString_FromString("Hello world"); + """), + ("test_Size", "METH_NOARGS", + """ + PyObject* s = PyString_FromString("Hello world"); + int result = 0; + + if(PyString_Size(s) == 11) { + result = 1; + } + Py_DECREF(s); + return PyBool_FromLong(result); + """), + ("test_Size_exception", "METH_NOARGS", + """ + PyObject* f = PyFloat_FromDouble(1.0); + Py_ssize_t size = PyString_Size(f); + + Py_DECREF(f); + return NULL; + """), + ]) assert module.get_hello1() == 'Hello world' assert module.get_hello2() == 'Hello world' assert module.test_Size() From arigo at codespeak.net Mon Mar 22 14:46:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 14:46:47 +0100 (CET) Subject: [pypy-svn] r72554 - in pypy/trunk/pypy: rpython/lltypesystem/test translator/c/src Message-ID: <20100322134647.EF7F9282B90@codespeak.net> Author: arigo Date: Mon Mar 22 14:46:46 2010 New Revision: 72554 Removed: pypy/trunk/pypy/translator/c/src/standalone.h Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py pypy/trunk/pypy/translator/c/src/allocator.h pypy/trunk/pypy/translator/c/src/g_include.h Log: Move stuff around the .h files, in order to fix test_rffi. Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_rffi.py Mon Mar 22 14:46:46 2010 @@ -85,6 +85,7 @@ def test_string_reverse(self): c_source = py.code.Source(""" #include + #include #include char *f(char* arg) Modified: pypy/trunk/pypy/translator/c/src/allocator.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/allocator.h (original) +++ pypy/trunk/pypy/translator/c/src/allocator.h Mon Mar 22 14:46:46 2010 @@ -1,4 +1,10 @@ +/* allocation functions prototypes */ +void *PyObject_Malloc(size_t n); +void *PyObject_Realloc(void *p, size_t n); +void PyObject_Free(void *p); + + #ifndef PYPY_NOT_MAIN_FILE #ifdef AVR #ifndef NO_OBMALLOC 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 Mon Mar 22 14:46:46 2010 @@ -11,7 +11,9 @@ # include "marshal.h" # include "eval.h" #else -# include "src/standalone.h" +# include +# include +# include #endif #include "src/mem.h" From arigo at codespeak.net Mon Mar 22 14:51:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 14:51:58 +0100 (CET) Subject: [pypy-svn] r72555 - pypy/branch/fix-64 Message-ID: <20100322135158.72FA7282B90@codespeak.net> Author: arigo Date: Mon Mar 22 14:51:57 2010 New Revision: 72555 Added: pypy/branch/fix-64/ - copied from r72554, pypy/trunk/ Log: A branch in which to put all fixes to tests for 64-bit Linux. From arigo at codespeak.net Mon Mar 22 14:53:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 14:53:00 +0100 (CET) Subject: [pypy-svn] r72556 - in pypy/branch/fix-64/pypy/rpython/lltypesystem: . test Message-ID: <20100322135300.3B593282B90@codespeak.net> Author: arigo Date: Mon Mar 22 14:52:58 2010 New Revision: 72556 Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/llgroup.py pypy/branch/fix-64/pypy/rpython/lltypesystem/test/test_llgroup.py Log: Fix test_llgroup. Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/llgroup.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/lltypesystem/llgroup.py (original) +++ pypy/branch/fix-64/pypy/rpython/lltypesystem/llgroup.py Mon Mar 22 14:52:58 2010 @@ -97,7 +97,8 @@ '&~0xFFFF' or with a direct masking like '&0x10000' (resp. on 64-bit platform, with '&~0xFFFFFFFF' or '&0x100000000'). """ - MASK = (1<<(LONG_BIT//2))-1 # 0xFFFF or 0xFFFFFFFF + SHIFT = LONG_BIT//2 + MASK = (1< Author: arigo Date: Mon Mar 22 14:59:13 2010 New Revision: 72557 Modified: pypy/branch/fix-64/pypy/jit/backend/llsupport/gc.py pypy/branch/fix-64/pypy/rpython/lltypesystem/llgroup.py pypy/branch/fix-64/pypy/rpython/lltypesystem/test/test_llgroup.py Log: More test fixes. Modified: pypy/branch/fix-64/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/fix-64/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/fix-64/pypy/jit/backend/llsupport/gc.py Mon Mar 22 14:59:13 2010 @@ -2,6 +2,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import fatalerror from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr +from pypy.rpython.lltypesystem import llgroup from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -309,7 +310,7 @@ # if convenient for the backend, we also compute the info about # the flag as (byte-offset, single-byte-flag). import struct - value = struct.pack("i", self.jit_wb_if_flag) + value = struct.pack("l", self.jit_wb_if_flag) assert value.count('\x00') == len(value) - 1 # only one byte is != 0 i = 0 while value[i] == '\x00': i += 1 @@ -372,8 +373,8 @@ # make a malloc function, with three arguments def malloc_basic(size, tid): - type_id = llop.extract_ushort(rffi.USHORT, tid) - has_finalizer = bool(tid & (1<<16)) + type_id = llop.extract_ushort(llgroup.HALFWORD, tid) + has_finalizer = bool(tid & (1< Author: afa Date: Mon Mar 22 15:02:16 2010 New Revision: 72558 Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py pypy/trunk/pypy/module/cpyext/test/test_floatobject.py pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Log: use the new function to create modules Modified: pypy/trunk/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_boolobject.py Mon Mar 22 15:02:16 2010 @@ -5,61 +5,41 @@ class AppTestBoolObject(AppTestCpythonExtensionBase): def test_boolobject(self): - import sys - init = """ - if (Py_IsInitialized()) - Py_InitModule("foo", methods); - """ - body = """ - static PyObject* foo_get_true(PyObject* self, PyObject *args) - { - Py_RETURN_TRUE; - } - static PyObject* foo_get_false(PyObject* self, PyObject *args) - { - Py_RETURN_FALSE; - } - static PyObject* foo_test_FromLong(PyObject* self, PyObject *args) - { - int i; - for(i=-3; i<3; i++) - { - PyObject* obj = PyBool_FromLong(i); - PyObject* expected = (i ? Py_True : Py_False); - - if(obj != expected) - { - Py_DECREF(obj); - Py_RETURN_FALSE; - } - Py_DECREF(obj); - } - Py_RETURN_TRUE; - } - static PyObject* foo_test_Check(PyObject* self, PyObject *args) - { - int result = 0; - PyObject* f = PyFloat_FromDouble(1.0); - - if(PyBool_Check(Py_True) && - PyBool_Check(Py_False) && - !PyBool_Check(f)) - { - result = 1; - } - Py_DECREF(f); - return PyBool_FromLong(result); - } - static PyMethodDef methods[] = { - { "get_true", foo_get_true, METH_NOARGS }, - { "get_false", foo_get_false, METH_NOARGS }, - { "test_FromLong", foo_test_FromLong, METH_NOARGS }, - { "test_Check", foo_test_Check, METH_NOARGS }, - { NULL } - }; - """ - module = self.import_module(name='foo', init=init, body=body) - assert 'foo' in sys.modules + module = self.import_extension('foo', [ + ("get_true", "METH_NOARGS", "Py_RETURN_TRUE;"), + ("get_false", "METH_NOARGS", "Py_RETURN_FALSE;"), + ("test_FromLong", "METH_NOARGS", + """ + int i; + for(i=-3; i<3; i++) + { + PyObject* obj = PyBool_FromLong(i); + PyObject* expected = (i ? Py_True : Py_False); + + if(obj != expected) + { + Py_DECREF(obj); + Py_RETURN_FALSE; + } + Py_DECREF(obj); + } + Py_RETURN_TRUE; + """), + ("test_Check", "METH_NOARGS", + """ + int result = 0; + PyObject* f = PyFloat_FromDouble(1.0); + + if(PyBool_Check(Py_True) && + PyBool_Check(Py_False) && + !PyBool_Check(f)) + { + result = 1; + } + Py_DECREF(f); + return PyBool_FromLong(result); + """), + ]) assert module.get_true() == True assert module.get_false() == False assert module.test_FromLong() == True Modified: pypy/trunk/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_floatobject.py Mon Mar 22 15:02:16 2010 @@ -5,30 +5,18 @@ class AppTestFloatObject(AppTestCpythonExtensionBase): def test_floatobject(self): - import sys - init = """ - if (Py_IsInitialized()) - Py_InitModule("foo", methods); - """ - body = """ - static PyObject* foo_FromDouble(PyObject* self, PyObject *args) - { - return PyFloat_FromDouble(3.14); - } - static PyObject* foo_AsDouble(PyObject* self, PyObject *args) - { - PyObject* obj = PyFloat_FromDouble(23.45); - double d = PyFloat_AsDouble(obj); - Py_DECREF(obj); - return PyFloat_FromDouble(d); - } - static PyMethodDef methods[] = { - { "FromDouble", foo_FromDouble, METH_NOARGS }, - { "AsDouble", foo_AsDouble, METH_NOARGS }, - { NULL } - }; - """ - module = self.import_module(name='foo', init=init, body=body) - assert 'foo' in sys.modules + module = self.import_extension('foo', [ + ("FromDouble", "METH_NOARGS", + """ + return PyFloat_FromDouble(3.14); + """), + ("AsDouble", "METH_NOARGS", + """ + PyObject* obj = PyFloat_FromDouble(23.45); + double d = PyFloat_AsDouble(obj); + Py_DECREF(obj); + return PyFloat_FromDouble(d); + """), + ]) assert module.FromDouble() == 3.14 assert module.AsDouble() == 23.45 Modified: pypy/trunk/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_stringobject.py Mon Mar 22 15:02:16 2010 @@ -38,4 +38,4 @@ assert module.get_hello1() == 'Hello world' assert module.get_hello2() == 'Hello world' assert module.test_Size() - raises(TypeError, "module.test_Size_exception()") + raises(TypeError, module.test_Size_exception) From arigo at codespeak.net Mon Mar 22 15:19:01 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 15:19:01 +0100 (CET) Subject: [pypy-svn] r72559 - in pypy/branch/fix-64/pypy/module/_socket: . test Message-ID: <20100322141901.6387F282B90@codespeak.net> Author: arigo Date: Mon Mar 22 15:18:59 2010 New Revision: 72559 Modified: pypy/branch/fix-64/pypy/module/_socket/interp_func.py pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py Log: Fix test_NtoH, and htons etc. Modified: pypy/branch/fix-64/pypy/module/_socket/interp_func.py ============================================================================== --- pypy/branch/fix-64/pypy/module/_socket/interp_func.py (original) +++ pypy/branch/fix-64/pypy/module/_socket/interp_func.py Mon Mar 22 15:18:59 2010 @@ -2,6 +2,7 @@ from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError +from pypy.rlib.rarithmetic import r_uint from pypy.interpreter.error import OperationError, operationerrfmt def gethostname(space): @@ -152,30 +153,24 @@ return space.newtuple([space.wrap(sock1), space.wrap(sock2)]) socketpair.unwrap_spec = [ObjSpace, int, int, int] +# The following 4 functions refuse all negative numbers, like CPython 2.6. +# They could also check that the argument is not too large, but CPython 2.6 +# is not doing that consistently. def ntohs(space, x): """ntohs(integer) -> integer Convert a 16-bit integer from network to host byte order. """ return space.wrap(rsocket.ntohs(x)) -ntohs.unwrap_spec = [ObjSpace, int] +ntohs.unwrap_spec = [ObjSpace, r_uint] -def ntohl(space, w_x): +def ntohl(space, x): """ntohl(integer) -> integer Convert a 32-bit integer from network to host byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.ntohl(x)) -ntohl.unwrap_spec = [ObjSpace, W_Root] +ntohl.unwrap_spec = [ObjSpace, r_uint] def htons(space, x): """htons(integer) -> integer @@ -183,24 +178,15 @@ Convert a 16-bit integer from host to network byte order. """ return space.wrap(rsocket.htons(x)) -htons.unwrap_spec = [ObjSpace, int] +htons.unwrap_spec = [ObjSpace, r_uint] -def htonl(space, w_x): +def htonl(space, x): """htonl(integer) -> integer Convert a 32-bit integer from host to network byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.htonl(x)) -htonl.unwrap_spec = [ObjSpace, W_Root] +htonl.unwrap_spec = [ObjSpace, r_uint] def inet_aton(space, ip): """inet_aton(string) -> packed 32-bit IP representation Modified: pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py ============================================================================== --- pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py (original) +++ pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py Mon Mar 22 15:18:59 2010 @@ -335,6 +335,7 @@ s.close() def test_NtoH(self): + import sys import _socket as socket # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. @@ -348,7 +349,28 @@ swapped = func(mask) assert swapped & mask == mask try: - func(1L<<34) + func(-1) + except (OverflowError, ValueError): + pass + else: + assert False + try: + func(sys.maxint*2+2) + except OverflowError: + pass + else: + assert False + + def test_NtoH_overflow(self): + skip("we are not checking for overflowing values yet") + import _socket as socket + # Checks that we cannot give too large values to htons etc. + # Skipped for now; CPython 2.6 is also not consistent. + sizes = {socket.htonl: 32, socket.ntohl: 32, + socket.htons: 16, socket.ntohs: 16} + for func, size in sizes.items(): + try: + func(1L << size) except OverflowError: pass else: From arigo at codespeak.net Mon Mar 22 15:59:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 15:59:32 +0100 (CET) Subject: [pypy-svn] r72562 - in pypy/branch/fix-64/pypy: interpreter interpreter/test module/posix module/posix/test Message-ID: <20100322145932.2C505282B90@codespeak.net> Author: arigo Date: Mon Mar 22 15:59:30 2010 New Revision: 72562 Modified: pypy/branch/fix-64/pypy/interpreter/baseobjspace.py pypy/branch/fix-64/pypy/interpreter/gateway.py pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py pypy/branch/fix-64/pypy/module/posix/interp_posix.py pypy/branch/fix-64/pypy/module/posix/test/test_posix2.py Log: Tweaks. Add to unwrap_spec the entry 'c_int' and 'c_uint', meaning a C-sized int or unsigned int. You still get an RPython integer, but if you are on a 64-bit platform and the integer would not fix a C-level 'int', then you get an OverflowError. Modified: pypy/branch/fix-64/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/fix-64/pypy/interpreter/baseobjspace.py Mon Mar 22 15:59:30 2010 @@ -9,11 +9,14 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer +from pypy.rlib.rarithmetic import r_uint from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +UINT_MAX_32_BITS = r_uint(4294967295) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -1095,6 +1098,24 @@ self.wrap("expected a non-negative integer")) return value + def c_int_w(self, w_obj): + # Like space.int_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.int_w(w_obj) + if value < -2147483647-1 or value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit integer")) + return value + + def c_uint_w(self, w_obj): + # Like space.uint_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.uint_w(w_obj) + if value > UINT_MAX_32_BITS: + raise OperationError(self.w_OverflowError, + self.wrap("expected an unsigned 32-bit integer")) + return value + def warn(self, msg, w_warningcls): self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): import warnings Modified: pypy/branch/fix-64/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/gateway.py (original) +++ pypy/branch/fix-64/pypy/interpreter/gateway.py Mon Mar 22 15:59:30 2010 @@ -126,6 +126,12 @@ def visit_nonnegint(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_c_int(self, el, app_sig): + self.checked_space_method(el, app_sig) + + def visit_c_uint(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() @@ -230,6 +236,12 @@ def visit_nonnegint(self, typ): self.run_args.append("space.nonnegint_w(%s)" % (self.scopenext(),)) + def visit_c_int(self, typ): + self.run_args.append("space.c_int_w(%s)" % (self.scopenext(),)) + + def visit_c_uint(self, typ): + self.run_args.append("space.c_uint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -348,6 +360,12 @@ def visit_nonnegint(self, typ): self.unwrap.append("space.nonnegint_w(%s)" % (self.nextarg(),)) + def visit_c_int(self, typ): + self.unwrap.append("space.c_int_w(%s)" % (self.nextarg(),)) + + def visit_c_uint(self, typ): + self.unwrap.append("space.c_uint_w(%s)" % (self.nextarg(),)) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) Modified: pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py Mon Mar 22 15:59:30 2010 @@ -197,6 +197,40 @@ space.raises_w(space.w_ValueError, space.call_function, w_app_g, space.wrap(-1)) + def test_interp2app_unwrap_spec_c_int(self): + from pypy.rlib.rarithmetic import r_longlong + space = self.space + w = space.wrap + def g(space, x): + return space.wrap(x + 6) + app_g = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_int']) + app_ug = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_uint']) + assert app_ug is not app_g + w_app_g = space.wrap(app_g) + w_app_ug = space.wrap(app_ug) + # + assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(-0x80000001))) + # + assert self.space.eq_w(space.call_function(w_app_ug, space.wrap(7)), + space.wrap(13)) + assert self.space.eq_w(space.call_function(w_app_ug, + space.wrap(0x7FFFFFFF)), + space.wrap(r_longlong(0x7FFFFFFF+6))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ug, space.wrap(-1)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ug, + space.wrap(r_longlong(0x100000000))) + def test_interp2app_unwrap_spec_args_w(self): space = self.space w = space.wrap Modified: pypy/branch/fix-64/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/branch/fix-64/pypy/module/posix/interp_posix.py (original) +++ pypy/branch/fix-64/pypy/module/posix/interp_posix.py Mon Mar 22 15:59:30 2010 @@ -20,7 +20,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(fd) -open.unwrap_spec = [ObjSpace, str, int, int] +open.unwrap_spec = [ObjSpace, str, "c_int", "c_int"] def lseek(space, fd, pos, how): """Set the current position of a file descriptor. Return the new position. @@ -32,7 +32,7 @@ raise wrap_oserror(space, e) else: return space.wrap(pos) -lseek.unwrap_spec = [ObjSpace, int, r_longlong, int] +lseek.unwrap_spec = [ObjSpace, "c_int", r_longlong, "c_int"] def isatty(space, fd): """Return True if 'fd' is an open file descriptor connected to the @@ -43,7 +43,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -isatty.unwrap_spec = [ObjSpace, int] +isatty.unwrap_spec = [ObjSpace, "c_int"] def read(space, fd, buffersize): """Read data from a file descriptor.""" @@ -53,7 +53,7 @@ raise wrap_oserror(space, e) else: return space.wrap(s) -read.unwrap_spec = [ObjSpace, int, int] +read.unwrap_spec = [ObjSpace, "c_int", int] def write(space, fd, data): """Write a string to a file descriptor. Return the number of bytes @@ -64,7 +64,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -write.unwrap_spec = [ObjSpace, int, 'bufferstr'] +write.unwrap_spec = [ObjSpace, "c_int", 'bufferstr'] def close(space, fd): """Close a file descriptor (for low level IO).""" @@ -72,12 +72,12 @@ os.close(fd) except OSError, e: raise wrap_oserror(space, e) -close.unwrap_spec = [ObjSpace, int] +close.unwrap_spec = [ObjSpace, "c_int"] def closerange(fd_low, fd_high): """Closes all file descriptors in [fd_low, fd_high), ignoring errors.""" rposix.closerange(fd_low, fd_high) -closerange.unwrap_spec = [int, int] +closerange.unwrap_spec = ["c_int", "c_int"] def ftruncate(space, fd, length): """Truncate a file to a specified length.""" @@ -85,21 +85,21 @@ os.ftruncate(fd, length) except OSError, e: raise wrap_oserror(space, e) -ftruncate.unwrap_spec = [ObjSpace, int, r_longlong] +ftruncate.unwrap_spec = [ObjSpace, "c_int", r_longlong] def fsync(space, fd): try: os.fsync(fd) except OSError, e: raise wrap_oserror(space, e) -fsync.unwrap_spec = [ObjSpace, int] +fsync.unwrap_spec = [ObjSpace, "c_int"] def fdatasync(space, fd): try: os.fdatasync(fd) except OSError, e: raise wrap_oserror(space, e) -fdatasync.unwrap_spec = [ObjSpace, int] +fdatasync.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -157,7 +157,7 @@ raise wrap_oserror(space, e) else: return build_stat_result(space, st) -fstat.unwrap_spec = [ObjSpace, int] +fstat.unwrap_spec = [ObjSpace, "c_int"] def stat(space, path): """Perform a stat system call on the given path. Return an object @@ -221,7 +221,7 @@ raise wrap_oserror(space, e) else: return space.wrap(newfd) -dup.unwrap_spec = [ObjSpace, int] +dup.unwrap_spec = [ObjSpace, "c_int"] def dup2(space, old_fd, new_fd): """Duplicate a file descriptor.""" @@ -229,7 +229,7 @@ os.dup2(old_fd, new_fd) except OSError, e: raise wrap_oserror(space, e) -dup2.unwrap_spec = [ObjSpace, int, int] +dup2.unwrap_spec = [ObjSpace, "c_int", "c_int"] def access(space, path, mode): """ @@ -247,7 +247,7 @@ raise wrap_oserror(space, e) else: return space.wrap(ok) -access.unwrap_spec = [ObjSpace, str, int] +access.unwrap_spec = [ObjSpace, str, "c_int"] def times(space): @@ -335,7 +335,7 @@ os.mkdir(path, mode) except OSError, e: raise wrap_oserror(space, e) -mkdir.unwrap_spec = [ObjSpace, str, int] +mkdir.unwrap_spec = [ObjSpace, str, "c_int"] def rmdir(space, path): """Remove a directory.""" @@ -353,7 +353,7 @@ raise OperationError(space.w_ValueError, space.wrap("strerror() argument out of range")) return space.wrap(text) -strerror.unwrap_spec = [ObjSpace, int] +strerror.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -440,7 +440,7 @@ os.chmod(path, mode) except OSError, e: raise wrap_oserror(space, e) -chmod.unwrap_spec = [ObjSpace, str, int] +chmod.unwrap_spec = [ObjSpace, str, "c_int"] def rename(space, old, new): "Rename a file or directory." @@ -454,7 +454,7 @@ "Set the current numeric umask and return the previous umask." prevmask = os.umask(mask) return space.wrap(prevmask) -umask.unwrap_spec = [ObjSpace, int] +umask.unwrap_spec = [ObjSpace, "c_int"] def getpid(space): "Return the current process id." @@ -471,7 +471,7 @@ os.kill(pid, sig) except OSError, e: raise wrap_oserror(space, e) -kill.unwrap_spec = [ObjSpace, int, int] +kill.unwrap_spec = [ObjSpace, "c_int", "c_int"] def abort(space): """Abort the interpreter immediately. This 'dumps core' or otherwise fails @@ -531,11 +531,11 @@ except OSError, e: raise wrap_oserror(space, e) return space.newtuple([space.wrap(pid), space.wrap(status)]) -waitpid.unwrap_spec = [ObjSpace, int, int] +waitpid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def _exit(space, status): os._exit(status) -_exit.unwrap_spec = [ObjSpace, int] +_exit.unwrap_spec = [ObjSpace, "c_int"] def execv(space, command, w_args): """ execv(path, args) @@ -649,7 +649,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setuid.unwrap_spec = [ObjSpace, int] +setuid.unwrap_spec = [ObjSpace, "c_uint"] def seteuid(space, arg): """ seteuid(uid) @@ -661,7 +661,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -seteuid.unwrap_spec = [ObjSpace, int] +seteuid.unwrap_spec = [ObjSpace, "c_uint"] def setgid(space, arg): """ setgid(gid) @@ -673,7 +673,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setgid.unwrap_spec = [ObjSpace, int] +setgid.unwrap_spec = [ObjSpace, "c_uint"] def setegid(space, arg): """ setegid(gid) @@ -685,7 +685,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setegid.unwrap_spec = [ObjSpace, int] +setegid.unwrap_spec = [ObjSpace, "c_uint"] def chroot(space, path): """ chroot(path) @@ -761,7 +761,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(pgid) -getpgid.unwrap_spec = [ObjSpace, int] +getpgid.unwrap_spec = [ObjSpace, "c_int"] def setpgid(space, pid, pgrp): """ setpgid(pid, pgrp) @@ -773,7 +773,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setpgid.unwrap_spec = [ObjSpace, int, int] +setpgid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def setreuid(space, ruid, euid): """ setreuid(ruid, euid) @@ -785,7 +785,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setreuid.unwrap_spec = [ObjSpace, int, int] +setreuid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] def setregid(space, rgid, egid): """ setregid(rgid, egid) @@ -797,7 +797,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setregid.unwrap_spec = [ObjSpace, int, int] +setregid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] def getsid(space, pid): """ getsid(pid) -> sid @@ -809,7 +809,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(sid) -getsid.unwrap_spec = [ObjSpace, int] +getsid.unwrap_spec = [ObjSpace, "c_int"] def setsid(space): """ setsid() @@ -831,7 +831,7 @@ def WSTAR(space, status): return space.newbool(getattr(os, name)(status)) WSTAR.__doc__ = getattr(os, name).__doc__ - WSTAR.unwrap_spec = [ObjSpace, int] + WSTAR.unwrap_spec = [ObjSpace, "c_int"] WSTAR.func_name = name return WSTAR @@ -845,7 +845,7 @@ return space.wrap(os.ttyname(fd)) except OSError, e: raise wrap_oserror(space, e) -ttyname.unwrap_spec = [ObjSpace, int] +ttyname.unwrap_spec = [ObjSpace, "c_int"] def sysconf(space, w_num_or_name): # XXX slightly non-nice, reuses the sysconf of the underlying os module @@ -866,7 +866,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -chown.unwrap_spec = [ObjSpace, str, int, int] +chown.unwrap_spec = [ObjSpace, str, "c_uint", "c_uint"] if _WIN: from pypy.rlib import rwin32 Modified: pypy/branch/fix-64/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/branch/fix-64/pypy/module/posix/test/test_posix2.py (original) +++ pypy/branch/fix-64/pypy/module/posix/test/test_posix2.py Mon Mar 22 15:59:30 2010 @@ -380,7 +380,7 @@ if hasattr(os, 'setuid'): def test_os_setuid_error(self): os = self.posix - raises(OSError, os.setuid, -100000) + raises((OSError, ValueError, OverflowError), os.setuid, -100000) if hasattr(os, 'getgid'): def test_os_getgid(self): @@ -396,13 +396,13 @@ if hasattr(os, 'setgid'): def test_os_setgid_error(self): os = self.posix - raises(OSError, os.setgid, -100000) + raises((OSError, ValueError, OverflowError), os.setgid, -100000) if hasattr(os, 'getsid'): def test_os_getsid(self): os = self.posix assert os.getsid(0) == self.getsid0 - raises(OSError, os.getsid, -100000) + raises((OSError, ValueError, OverflowError), os.getsid, -100000) if hasattr(os, 'sysconf'): def test_os_sysconf(self): From afa at codespeak.net Mon Mar 22 16:02:04 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 16:02:04 +0100 (CET) Subject: [pypy-svn] r72563 - pypy/trunk/pypy/module/cpyext/include Message-ID: <20100322150204.77492282B90@codespeak.net> Author: afa Date: Mon Mar 22 16:02:02 2010 New Revision: 72563 Modified: pypy/trunk/pypy/module/cpyext/include/varargwrapper.c Log: How could this possibly have worked? Modified: pypy/trunk/pypy/module/cpyext/include/varargwrapper.c ============================================================================== --- pypy/trunk/pypy/module/cpyext/include/varargwrapper.c (original) +++ pypy/trunk/pypy/module/cpyext/include/varargwrapper.c Mon Mar 22 16:02:02 2010 @@ -10,7 +10,8 @@ tuple = PyTuple_New(size); va_start(ap, size); - for (i = 0; i < size; cur = va_arg(ap, PyObject*), i++) { + for (i = 0; i < size; i++) { + cur = va_arg(ap, PyObject*); Py_INCREF(cur); if (PyTuple_SetItem(tuple, i, cur) < 0) return NULL; From arigo at codespeak.net Mon Mar 22 16:12:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 16:12:21 +0100 (CET) Subject: [pypy-svn] r72564 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100322151221.473BD282B90@codespeak.net> Author: arigo Date: Mon Mar 22 16:12:19 2010 New Revision: 72564 Modified: pypy/trunk/pypy/objspace/std/floatobject.py pypy/trunk/pypy/objspace/std/test/test_floatobject.py Log: Say that x**y on floats delegates directly to math.pow(x,y). That seems the sanest implementation, and I don't care enough that on CPython 2.6, math.pow(-1.0, 1e200) gives ValueError but (-1.0)**1e200 gives 1.0. Modified: pypy/trunk/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/floatobject.py Mon Mar 22 16:12:19 2010 @@ -302,9 +302,6 @@ return space.newtuple(_divmod_w(space, w_float1, w_float2)) def pow__Float_Float_ANY(space, w_float1, w_float2, thirdArg): - # XXX it makes sense to do more here than in the backend - # about sorting out errors! - # This raises FailedToImplement in cases like overflow where a # (purely theoretical) big-precision float implementation would have # a chance to give a result, and directly OperationError for errors @@ -314,34 +311,18 @@ "pow() 3rd argument not allowed unless all arguments are integers")) x = w_float1.floatval y = w_float2.floatval - z = 1.0 - if y == 0.0: - z = 1.0 - elif x == 0.0: - if y < 0.0: + try: + # We delegate to our implementation of math.pow() the error detection. + z = math.pow(x,y) + except OverflowError: + raise FailedToImplementArgs(space.w_OverflowError, + space.wrap("float power")) + except ValueError: + if x == 0.0 and y < 0.0: raise OperationError(space.w_ZeroDivisionError, - space.wrap("0.0 cannot be raised to a negative power")) - z = 0.0 - else: - if x < 0.0: - if math.floor(y) != y: - raise OperationError(space.w_ValueError, - space.wrap("negative number " - "cannot be raised to a fractional power")) - if x == -1.0: - # xxx what if y is infinity or a NaN - if math.floor(y * 0.5) * 2.0 == y: - return space.wrap(1.0) - else: - return space.wrap( -1.0) -# else: - try: - z = math.pow(x,y) - except OverflowError: - raise FailedToImplementArgs(space.w_OverflowError, space.wrap("float power")) - except ValueError: - raise FailedToImplementArgs(space.w_ValueError, space.wrap("float power")) # xxx - + space.wrap("0.0 cannot be raised to a negative power")) + raise OperationError(space.w_ValueError, + space.wrap("float power")) return W_FloatObject(z) Modified: pypy/trunk/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_floatobject.py Mon Mar 22 16:12:19 2010 @@ -146,7 +146,8 @@ raises(ValueError, pw, -1.0, 0.5) assert pw(-1.0, 2.0) == 1.0 assert pw(-1.0, 3.0) == -1.0 - assert pw(-1.0, 1e200) == 1.0 + #assert pw(-1.0, 1e200) == 1.0 -- either 1.0, or ValueError, are + # -- acceptable answers IMHO def test_pow_neg_base(self): def pw(x, y): From afa at codespeak.net Mon Mar 22 16:16:40 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 16:16:40 +0100 (CET) Subject: [pypy-svn] r72565 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322151640.A91BE282B90@codespeak.net> Author: afa Date: Mon Mar 22 16:16:39 2010 New Revision: 72565 Modified: pypy/trunk/pypy/module/cpyext/__init__.py pypy/trunk/pypy/module/cpyext/api.py Log: Rewrite load_extension_module to use libffi instead of ctypes and expose it at app-level Modified: pypy/trunk/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/__init__.py (original) +++ pypy/trunk/pypy/module/cpyext/__init__.py Mon Mar 22 16:16:39 2010 @@ -6,6 +6,7 @@ class Module(MixedModule): interpleveldefs = { + 'load_module': 'api.load_extension_module', } appleveldefs = { Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 16:16:39 2010 @@ -328,10 +328,14 @@ return modulename.new(ext='') + at unwrap_spec(ObjSpace, str, str) def load_extension_module(space, path, name): state = space.fromcache(State) - import ctypes - initfunc = ctypes.CDLL(path)['init%s' % (name,)] - initfunc() + from pypy.rlib import libffi + dll = libffi.CDLL(path) + initfunc = dll.getpointer( + 'init%s' % (name,), [], libffi.ffi_type_void) + dll.unload_on_finalization = False + initfunc.call(lltype.Void) state.check_and_raise_exception() From arigo at codespeak.net Mon Mar 22 16:28:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 16:28:13 +0100 (CET) Subject: [pypy-svn] r72568 - pypy/trunk/pypy/translator/c/src Message-ID: <20100322152813.9338B282B90@codespeak.net> Author: arigo Date: Mon Mar 22 16:28:11 2010 New Revision: 72568 Modified: pypy/trunk/pypy/translator/c/src/thread_pthread.h Log: Silence a warning in case we compile in non-standalone mode. Modified: pypy/trunk/pypy/translator/c/src/thread_pthread.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/thread_pthread.h (original) +++ pypy/trunk/pypy/translator/c/src/thread_pthread.h Mon Mar 22 16:28:11 2010 @@ -16,7 +16,9 @@ /* The following is hopefully equivalent to what CPython does (which is trying to compile a snippet of code using it) */ #ifdef PTHREAD_SCOPE_SYSTEM -# define PTHREAD_SYSTEM_SCHED_SUPPORTED +# ifndef PTHREAD_SYSTEM_SCHED_SUPPORTED +# define PTHREAD_SYSTEM_SCHED_SUPPORTED +# endif #endif /* The POSIX spec says that implementations supporting the sem_* From xoraxax at codespeak.net Mon Mar 22 17:04:33 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 17:04:33 +0100 (CET) Subject: [pypy-svn] r72571 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322160433.E2F26282B90@codespeak.net> Author: xoraxax Date: Mon Mar 22 17:04:32 2010 New Revision: 72571 Modified: pypy/trunk/pypy/module/cpyext/api.py Log: Small cleanup. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 17:04:32 2010 @@ -307,10 +307,8 @@ return if restype is PyObject: return lltype.nullptr(PyObject.TO) - if restype is lltype.Signed: - return rffi.cast(lltype.Signed, -1) - if restype is rffi.INT_REAL: - return rffi.cast(rffi.INT_REAL, -1) + if restype in (Py_ssize_t, rffi.INT_real): + return rffi.cast(restype, -1) assert False, "Unknown return type" if callable.api_func.restype is PyObject: From afa at codespeak.net Mon Mar 22 17:21:19 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 17:21:19 +0100 (CET) Subject: [pypy-svn] r72574 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322162119.C3506282B90@codespeak.net> Author: afa Date: Mon Mar 22 17:21:18 2010 New Revision: 72574 Modified: pypy/trunk/pypy/module/cpyext/TODO Log: some ideas about PyStringObject Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Mon Mar 22 17:21:18 2010 @@ -1,3 +1,39 @@ - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject - Add exceptions - Generate header files programmatically. + +PyStringObject support +====================== + +The problem +----------- + +PyString_AsString() should return a (non-movable) pointer +to the underlying buffer, whereas pypy strings are movable. C code +may temporarily store this address and use it, as long as it owns a +reference to the PyObject. There is no "release" function to specify +that the pointer is not needed any more. + +Note that the pointer may be used to fill the initial value of +string. This is valid only when the string was just allocated, and is +not used elsewhere. + +Proposed solution +----------------- + +Our emulation of the PyStringObject contains an additional member: a +pointer to a char buffer; it may be NULL. + +- A string allocated by pypy will be converted into a PyStringObject + with a NULL buffer. When PyString_AsString() is called, memory is + allocated (with flavor='raw') and content is copied. + +- A string allocated with PyString_FromStringAndSize(NULL, size) will + allocate a buffer with the specified size, but the reference won't + be stored in the global map py_objects_r2w; there won't be a + corresponding object in pypy. When from_ref() or Py_INCREF() is + called, the pypy string is created, and added in py_objects_r2w. + The buffer is then supposed to be immutable. + +- There could be an (expensive!) check in from_ref() that the buffer + still corresponds to the pypy gc-managed string. From afa at codespeak.net Mon Mar 22 17:25:39 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 17:25:39 +0100 (CET) Subject: [pypy-svn] r72576 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322162539.EBE4B282B90@codespeak.net> Author: afa Date: Mon Mar 22 17:25:38 2010 New Revision: 72576 Modified: pypy/trunk/pypy/module/cpyext/TODO Log: Mention _PyString_Resize Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Mon Mar 22 17:25:38 2010 @@ -35,5 +35,8 @@ called, the pypy string is created, and added in py_objects_r2w. The buffer is then supposed to be immutable. +- _PyString_Resize works only on not-yet-pypy'd strings, and returns a + similar object. + - There could be an (expensive!) check in from_ref() that the buffer still corresponds to the pypy gc-managed string. From afa at codespeak.net Mon Mar 22 17:48:35 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 17:48:35 +0100 (CET) Subject: [pypy-svn] r72578 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322164835.1E4C5282BAD@codespeak.net> Author: afa Date: Mon Mar 22 17:48:34 2010 New Revision: 72578 Modified: pypy/trunk/pypy/module/cpyext/TODO Log: Mention PyString_Size() Modified: pypy/trunk/pypy/module/cpyext/TODO ============================================================================== --- pypy/trunk/pypy/module/cpyext/TODO (original) +++ pypy/trunk/pypy/module/cpyext/TODO Mon Mar 22 17:48:34 2010 @@ -38,5 +38,8 @@ - _PyString_Resize works only on not-yet-pypy'd strings, and returns a similar object. +- PyString_Size don't need to force the object. (in this case, another + "size" member is needed) + - There could be an (expensive!) check in from_ref() that the buffer still corresponds to the pypy gc-managed string. From arigo at codespeak.net Mon Mar 22 17:55:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 17:55:06 +0100 (CET) Subject: [pypy-svn] r72579 - in pypy/trunk/pypy/translator/c: . src Message-ID: <20100322165506.A5FE8282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 17:55:05 2010 New Revision: 72579 Modified: pypy/trunk/pypy/translator/c/funcgen.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/primitive.py pypy/trunk/pypy/translator/c/src/support.h Log: Silence some more C compilation warnings. Modified: pypy/trunk/pypy/translator/c/funcgen.py ============================================================================== --- pypy/trunk/pypy/translator/c/funcgen.py (original) +++ pypy/trunk/pypy/translator/c/funcgen.py Mon Mar 22 17:55:05 2010 @@ -485,16 +485,20 @@ assert isinstance(op.args[1], Constant) STRUCT = self.lltypemap(op.args[0]).TO structdef = self.db.gettypedefnode(STRUCT) + baseexpr_is_const = isinstance(op.args[0], Constant) expr = ampersand + structdef.ptr_access_expr(self.expr(op.args[0]), - op.args[1].value) + op.args[1].value, + baseexpr_is_const) return self.generic_get(op, expr) def OP_BARE_SETFIELD(self, op): assert isinstance(op.args[1], Constant) STRUCT = self.lltypemap(op.args[0]).TO structdef = self.db.gettypedefnode(STRUCT) + baseexpr_is_const = isinstance(op.args[0], Constant) expr = structdef.ptr_access_expr(self.expr(op.args[0]), - op.args[1].value) + op.args[1].value, + baseexpr_is_const) return self.generic_set(op, expr) def OP_GETSUBSTRUCT(self, op): Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Mon Mar 22 17:55:05 2010 @@ -130,8 +130,10 @@ fldname = self.c_struct_field_name(fldname) return '%s.%s' % (baseexpr, fldname) - def ptr_access_expr(self, baseexpr, fldname): + def ptr_access_expr(self, baseexpr, fldname, baseexpr_is_const=False): fldname = self.c_struct_field_name(fldname) + if baseexpr_is_const: + return '%s->%s' % (baseexpr, fldname) return 'RPyField(%s, %s)' % (baseexpr, fldname) def definition(self): Modified: pypy/trunk/pypy/translator/c/primitive.py ============================================================================== --- pypy/trunk/pypy/translator/c/primitive.py (original) +++ pypy/trunk/pypy/translator/c/primitive.py Mon Mar 22 17:55:05 2010 @@ -95,7 +95,9 @@ elif isnan(value): return '(Py_HUGE_VAL/Py_HUGE_VAL)' else: - return repr(value) + x = repr(value) + assert not x.startswith('n') + return x def name_singlefloat(value, db): value = float(value) Modified: pypy/trunk/pypy/translator/c/src/support.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/support.h (original) +++ pypy/trunk/pypy/translator/c/src/support.h Mon Mar 22 17:55:05 2010 @@ -74,7 +74,7 @@ * it's a "guaranteed" segfault and not one that can be used by * attackers. */ -# define RPyCHECK(x) ((x) || RPyAbort()) +# define RPyCHECK(x) ((x)?(void)0:RPyAbort()) # define RPyField(ptr, name) ((RPyCHECK(ptr), (ptr))->name) # define RPyItem(array, index) \ ((RPyCHECK((index) >= 0 && (index) < (array)->length), \ @@ -87,12 +87,11 @@ # define RPyBareItem(array, index) \ ((RPyCHECK((array) && (index) >= 0), (array))[index]) -int RPyAbort(void); +void RPyAbort(void); #ifndef PYPY_NOT_MAIN_FILE -int RPyAbort(void) { +void RPyAbort(void) { fprintf(stderr, "Invalid RPython operation (NULL ptr or bad array index)\n"); abort(); - return 0; } #endif From afa at codespeak.net Mon Mar 22 18:17:07 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 18:17:07 +0100 (CET) Subject: [pypy-svn] r72581 - pypy/trunk/pypy/module/cpyext Message-ID: <20100322171707.3C09B282BAD@codespeak.net> Author: afa Date: Mon Mar 22 18:17:05 2010 New Revision: 72581 Modified: pypy/trunk/pypy/module/cpyext/stringobject.py Log: rffi has a nice function for PyString_FromStringAndSize(), use it Modified: pypy/trunk/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/stringobject.py (original) +++ pypy/trunk/pypy/module/cpyext/stringobject.py Mon Mar 22 18:17:05 2010 @@ -3,13 +3,8 @@ @cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) def PyString_FromStringAndSize(space, char_p, length): - l = [] - i = 0 - while length > 0: - l.append(char_p[i]) - i += 1 - length -= 1 - return space.wrap("".join(l)) + s = rffi.charpsize2str(char_p, length) + return space.wrap(s) @cpython_api([rffi.CCHARP], PyObject) def PyString_FromString(space, char_p): From xoraxax at codespeak.net Mon Mar 22 19:13:30 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 19:13:30 +0100 (CET) Subject: [pypy-svn] r72583 - pypy/trunk/pypy/interpreter Message-ID: <20100322181330.14BCD282BD4@codespeak.net> Author: xoraxax Date: Mon Mar 22 19:13:29 2010 New Revision: 72583 Modified: pypy/trunk/pypy/interpreter/typedef.py Log: Introduce support for GetSetPropertys that need to store data on their instance. This is necessary to support GetSetProperties in cpyext. The test coverage of GetSetProperty was doubled. Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Mon Mar 22 19:13:29 2010 @@ -301,7 +301,10 @@ # ____________________________________________________________ -def make_descr_typecheck_wrapper(func, extraargs=(), cls=None): +def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, cpy_property=False): + extra_arg = "" + if cpy_property: + extra_arg = "property, " if func is None: return None if cls is None: @@ -318,12 +321,12 @@ #print " value Read the value of the property of the given obj.""" @@ -400,7 +405,10 @@ return space.wrap(property) else: try: - return property.fget(space, w_obj) + if property.cpy_property: + return property.fget(property, space, w_obj) + else: + return property.fget(space, w_obj) except DescrMismatch, e: return w_obj.descr_call_mismatch(space, '__getattribute__',\ property.reqcls, Arguments(space, [w_obj, @@ -414,7 +422,10 @@ raise OperationError(space.w_TypeError, space.wrap("readonly attribute")) try: - fset(space, w_obj, w_value) + if property.cpy_property: + fset(property, space, w_obj, w_value) + else: + fset(space, w_obj, w_value) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__setattr__',\ property.reqcls, Arguments(space, [w_obj, @@ -428,7 +439,10 @@ raise OperationError(space.w_AttributeError, space.wrap("cannot delete attribute")) try: - fdel(space, w_obj) + if property.cpy_property: + fdel(space, w_obj) + else: + fdel(property, space, w_obj) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__delattr__',\ property.reqcls, Arguments(space, [w_obj, From xoraxax at codespeak.net Mon Mar 22 19:16:17 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 19:16:17 +0100 (CET) Subject: [pypy-svn] r72584 - in pypy/trunk/pypy/module/cpyext: . test Message-ID: <20100322181617.44461282BAD@codespeak.net> Author: xoraxax Date: Mon Mar 22 19:16:15 2010 New Revision: 72584 Modified: pypy/trunk/pypy/module/cpyext/api.py pypy/trunk/pypy/module/cpyext/methodobject.py pypy/trunk/pypy/module/cpyext/modsupport.py pypy/trunk/pypy/module/cpyext/test/test_typeobject.py pypy/trunk/pypy/module/cpyext/typeobject.py Log: Make getset properties working. Also pulled out from_ref_ex and generic_cpy_call, changed interface to convert_method_defs, changed debugging output. Modified: pypy/trunk/pypy/module/cpyext/api.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/api.py (original) +++ pypy/trunk/pypy/module/cpyext/api.py Mon Mar 22 19:16:15 2010 @@ -14,6 +14,7 @@ from pypy.translator import platform from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, unwrap_spec @@ -124,6 +125,7 @@ if w_obj is None: return lltype.nullptr(PyObject.TO) #raise NullPointerException("Trying to pass a NULL reference") + assert isinstance(w_obj, W_Root) state = space.fromcache(State) py_obj = state.py_objects_w2r.get(w_obj) if py_obj is None: @@ -281,7 +283,7 @@ def wrapper(*args): boxed_args = [] # XXX use unrolling_iterable here - print >>sys.stderr, callable + print >>sys.stderr, callable, for i, typ in enumerate(callable.api_func.argtypes): arg = args[i] if typ is PyObject: @@ -290,7 +292,7 @@ state = space.fromcache(State) try: retval = callable(space, *boxed_args) - print "Callable worked" + print >>sys.stderr, " DONE" except OperationError, e: e.normalize_exception(space) state.exc_type = e.w_type Modified: pypy/trunk/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/methodobject.py (original) +++ pypy/trunk/pypy/module/cpyext/methodobject.py Mon Mar 22 19:16:15 2010 @@ -1,4 +1,4 @@ -from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.baseobjspace import Wrappable, W_Root from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments @@ -12,6 +12,38 @@ from pypy.rlib.objectmodel import we_are_translated +def from_ref_ex(space, result): + try: + ret = from_ref(space, result) + except NullPointerException: + state = space.fromcache(State) + state.check_and_raise_exception() + assert False, "NULL returned but no exception set" + except InvalidPointerException: + if not we_are_translated(): + import sys + print >>sys.stderr, "Calling a C function return an invalid PyObject" \ + " pointer." + raise + return ret + +def generic_cpy_call(space, func, *args): + boxed_args = [] + for arg in args: # XXX ur needed + if isinstance(arg, W_Root) or arg is None: + boxed_args.append(make_ref(space, arg)) + else: + boxed_args.append(arg) + result = func(*boxed_args) + try: + ret = from_ref_ex(space, result) + Py_DECREF(space, ret) + return ret + finally: + for arg in args: # XXX ur needed + if arg is not None and isinstance(arg, W_Root): + Py_DECREF(space, arg) + # XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): acceptable_as_base_class = False @@ -25,26 +57,11 @@ # Call the C function if w_self is None: w_self = self.w_self - result = self.ml.c_ml_meth(make_ref(space, w_self), make_ref(space, args_tuple)) - try: - ret = from_ref(space, result) - Py_DECREF(space, ret) - if w_self: - Py_DECREF(space, w_self) - Py_DECREF(space, args_tuple) - except NullPointerException: - state = space.fromcache(State) - state.check_and_raise_exception() - assert False, "NULL returned but no exception set" - except InvalidPointerException: - if not we_are_translated(): - import sys - print >>sys.stderr, "Calling a C function return an invalid PyObject" \ - " pointer." - raise - return ret + return generic_cpy_call(space, self.ml.c_ml_meth, w_self, args_tuple) + class W_PyCMethodObject(W_PyCFunctionObject): + w_self = None def __init__(self, space, ml): self.space = space self.ml = ml Modified: pypy/trunk/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/modsupport.py (original) +++ pypy/trunk/pypy/module/cpyext/modsupport.py Mon Mar 22 19:16:15 2010 @@ -26,15 +26,15 @@ def Py_InitModule(space, name, methods): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) - dict_w = convert_method_defs(space, methods, None) + dict_w = {} + convert_method_defs(space, dict_w, methods, None) for key, w_value in dict_w.items(): space.setattr(w_mod, space.wrap(key), w_value) return w_mod -def convert_method_defs(space, methods, pto): +def convert_method_defs(space, dict_w, methods, pto): methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) - dict_w = {} if methods: i = -1 while True: @@ -63,7 +63,6 @@ else: w_obj = PyDescr_NewMethod(space, pto, method) dict_w[methodname] = w_obj - return dict_w @cpython_api([PyObject], rffi.INT_real) Modified: pypy/trunk/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/test/test_typeobject.py Mon Mar 22 19:16:15 2010 @@ -14,6 +14,6 @@ assert type(obj) is module.fooType print "type of obj has type", type(type(obj)) obj2 = obj.copy() + assert module.new().name == "Foo Example" skip("In progress") assert "copy" in repr(module.fooType.copy) - assert module.new().name == "Foo Example" Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Mon Mar 22 19:16:15 2010 @@ -7,13 +7,15 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.objectobject import W_ObjectObject -from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State +from pypy.module.cpyext.methodobject import from_ref_ex, generic_cpy_call + PyTypeObject = lltype.ForwardReference() PyTypeObjectPtr = lltype.Ptr(PyTypeObject) @@ -24,7 +26,7 @@ # XXX PyNumberMethods = PySequenceMethods = PyMappingMethods = \ - PyBufferProcs = PyMemberDef = PyGetSetDef = rffi.VOIDP.TO + PyBufferProcs = PyMemberDef = rffi.VOIDP.TO freefunc = P(FT([rffi.VOIDP], Void)) destructor = P(FT([PyO], Void)) @@ -64,6 +66,17 @@ visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT_real)) traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT_real)) +getter = P(FT([PyO, rffi.VOIDP_real], PyO)) +setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real)) + +PyGetSetDef = cpython_struct("PyGetSetDef", ( + ("name", rffi.CCHARP), + ("get", getter), + ("set", setter), + ("doc", rffi.CCHARP), + ("closure", rffi.VOIDP_real), +)) + PyTypeObjectFields = [] PyTypeObjectFields.extend(PyVarObjectFields) PyTypeObjectFields.extend([ @@ -138,16 +151,55 @@ ("tp_weaklist", PyObject), ("tp_del", destructor), ]) -PyTypeObject = cpython_struct( - "PyTypeObject", - PyTypeObjectFields, PyTypeObject) +cpython_struct("PyTypeObject", PyTypeObjectFields, PyTypeObject) + + + +class W_GetSetPropertyEx(GetSetProperty): # XXX fix this to be rpython + def getter(self, space, w_self): + return generic_cpy_call(space, self.getset.c_get, w_self, self.getset.c_closure) + + def setter(self, space, w_self, w_value): + return generic_cpy_call(space, self.getset.c_set, w_self, w_value, + self.getset.c_closure) + + def __init__(self, getset): + self.getset = getset + self.name = rffi.charp2str(getset.c_name) + doc = set = get = None + if doc: + doc = rffi.charp2str(getset.c_doc) + if getset.c_get: + get = self.getter.im_func + if getset.c_set: + set = self.setter.im_func + GetSetProperty.__init__(self, get, set, None, doc, W_PyCObject, True) + +def PyDescr_NewGetSet(space, getset, pto): + return space.wrap(W_GetSetPropertyEx(getset)) + +def convert_getset_defs(space, dict_w, getsets, pto): + getsets = rffi.cast(rffi.CArrayPtr(PyGetSetDef), getsets) + if getsets: + i = -1 + while True: + i = i + 1 + getset = getsets[i] + name = getset.c_name + if not name: + break + name = rffi.charp2str(name) + w_descr = PyDescr_NewGetSet(space, getset, pto) + dict_w[name] = w_descr class W_PyCTypeObject(W_TypeObject): def __init__(self, space, pto): self.pto = pto bases_w = [] - dict_w = convert_method_defs(space, pto.c_tp_methods, pto) + dict_w = {} + convert_method_defs(space, dict_w, pto.c_tp_methods, pto) + convert_getset_defs(space, dict_w, pto.c_tp_getset, pto) W_TypeObject.__init__(self, space, rffi.charp2str(pto.c_tp_name), bases_w or [space.w_object], dict_w) @@ -166,7 +218,6 @@ return pto def create_type_object(space, pto): - w_type = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) w_type.__init__(space, pto) w_type.ready() From arigo at codespeak.net Mon Mar 22 19:36:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 19:36:17 +0100 (CET) Subject: [pypy-svn] r72585 - in pypy/trunk/pypy/translator/goal: . test2 Message-ID: <20100322183617.2CE4F282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 19:36:15 2010 New Revision: 72585 Modified: pypy/trunk/pypy/translator/goal/app_main.py pypy/trunk/pypy/translator/goal/test2/test_app_main.py Log: Fix a test on Python 2.6, by using 'PYTHONINSPECT_' instead of 'PYTHONINSPECT'. 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 Mon Mar 22 19:36:15 2010 @@ -459,8 +459,6 @@ # obscure! try removing the following line, see how it crashes, and # guess why... ImStillAroundDontForgetMe = sys.modules['__main__'] - sys.ps1 = '>>>> ' - sys.ps2 = '.... ' # debugging only def pypy_initial_path(s): @@ -474,10 +472,20 @@ # finds its own extension modules :-/ import os os.environ['PYTHONPATH'] = ':'.join(sys.path) + reset = [] + if 'PYTHONINSPECT_' in os.environ: + reset.append(('PYTHONINSPECT', os.environ.get('PYTHONINSPECT', ''))) + os.environ['PYTHONINSPECT'] = os.environ['PYTHONINSPECT_'] from pypy.module.sys.version import PYPY_VERSION sys.pypy_version_info = PYPY_VERSION sys.pypy_initial_path = pypy_initial_path os = nanos.os_module_for_testing - sys.exit(entry_point(sys.argv[0], sys.argv[1:], os)) - #sys.exit(entry_point('app_main.py', sys.argv[1:])) + sys.ps1 = '>>>> ' + sys.ps2 = '.... ' + try: + sys.exit(int(entry_point(sys.argv[0], sys.argv[1:], os))) + finally: + sys.ps1 = '>>> ' # restore the normal ones, in case + sys.ps2 = '... ' # we are dropping to CPython's prompt + import os; os.environ.update(reset) Modified: pypy/trunk/pypy/translator/goal/test2/test_app_main.py ============================================================================== --- pypy/trunk/pypy/translator/goal/test2/test_app_main.py (original) +++ pypy/trunk/pypy/translator/goal/test2/test_app_main.py Mon Mar 22 19:36:15 2010 @@ -277,9 +277,8 @@ child.expect('>>> ') def test_pythoninspect(self): - old = os.environ.get('PYTHONINSPECT', '') + os.environ['PYTHONINSPECT_'] = '1' try: - os.environ['PYTHONINSPECT'] = '1' path = getscript(""" print 6*7 """) @@ -287,7 +286,7 @@ child.expect('42') child.expect('>>> ') finally: - os.environ['PYTHONINSPECT'] = old + del os.environ['PYTHONINSPECT_'] def test_set_pythoninspect(self): path = getscript(""" @@ -422,13 +421,12 @@ assert ('Argv: ' + repr([p, 'extra'])) in data def test_pythoninspect_doesnt_override_isatty(self): - old = os.environ.get('PYTHONINSPECT', '') + os.environ['PYTHONINSPECT_'] = '1' try: - os.environ['PYTHONINSPECT'] = '1' data = self.run('', senddata='6*7\nprint 2+3\n') assert data == '5\n' finally: - os.environ['PYTHONINSPECT'] = old + del os.environ['PYTHONINSPECT_'] def test_i_flag_overrides_isatty(self): data = self.run('-i', senddata='6*7\nraise SystemExit\n', From xoraxax at codespeak.net Mon Mar 22 19:42:44 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 19:42:44 +0100 (CET) Subject: [pypy-svn] r72586 - pypy/trunk/pypy/interpreter Message-ID: <20100322184244.C346F282BAD@codespeak.net> Author: xoraxax Date: Mon Mar 22 19:42:43 2010 New Revision: 72586 Modified: pypy/trunk/pypy/interpreter/typedef.py Log: Revert changes to typedef, does not translate. (svn merge -r 72583:72582 typedef.py). Modified: pypy/trunk/pypy/interpreter/typedef.py ============================================================================== --- pypy/trunk/pypy/interpreter/typedef.py (original) +++ pypy/trunk/pypy/interpreter/typedef.py Mon Mar 22 19:42:43 2010 @@ -301,10 +301,7 @@ # ____________________________________________________________ -def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, cpy_property=False): - extra_arg = "" - if cpy_property: - extra_arg = "property, " +def make_descr_typecheck_wrapper(func, extraargs=(), cls=None): if func is None: return None if cls is None: @@ -321,12 +318,12 @@ #print " value Read the value of the property of the given obj.""" @@ -405,10 +400,7 @@ return space.wrap(property) else: try: - if property.cpy_property: - return property.fget(property, space, w_obj) - else: - return property.fget(space, w_obj) + return property.fget(space, w_obj) except DescrMismatch, e: return w_obj.descr_call_mismatch(space, '__getattribute__',\ property.reqcls, Arguments(space, [w_obj, @@ -422,10 +414,7 @@ raise OperationError(space.w_TypeError, space.wrap("readonly attribute")) try: - if property.cpy_property: - fset(property, space, w_obj, w_value) - else: - fset(space, w_obj, w_value) + fset(space, w_obj, w_value) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__setattr__',\ property.reqcls, Arguments(space, [w_obj, @@ -439,10 +428,7 @@ raise OperationError(space.w_AttributeError, space.wrap("cannot delete attribute")) try: - if property.cpy_property: - fdel(space, w_obj) - else: - fdel(property, space, w_obj) + fdel(space, w_obj) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__delattr__',\ property.reqcls, Arguments(space, [w_obj, From arigo at codespeak.net Mon Mar 22 19:42:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 19:42:58 +0100 (CET) Subject: [pypy-svn] r72587 - pypy/branch/fix-64/pypy/rlib Message-ID: <20100322184258.1E97D282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 19:42:56 2010 New Revision: 72587 Modified: pypy/branch/fix-64/pypy/rlib/rstack.py Log: Fix. Modified: pypy/branch/fix-64/pypy/rlib/rstack.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/rstack.py (original) +++ pypy/branch/fix-64/pypy/rlib/rstack.py Mon Mar 22 19:42:56 2010 @@ -38,8 +38,9 @@ stack_too_big = rffi.llexternal('LL_stack_too_big', [], rffi.INT, compilation_info=compilation_info, _nowrapper=True, - _callable=lambda: 0, + _callable=lambda: _zero, sandboxsafe=True) +_zero = rffi.cast(rffi.INT, 0) def stack_check(): if rffi.cast(lltype.Signed, stack_too_big()): From afa at codespeak.net Mon Mar 22 19:48:02 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 22 Mar 2010 19:48:02 +0100 (CET) Subject: [pypy-svn] r72588 - pypy/branch/cpython-extension Message-ID: <20100322184802.88630282B90@codespeak.net> Author: afa Date: Mon Mar 22 19:48:01 2010 New Revision: 72588 Added: pypy/branch/cpython-extension/ - copied from r72587, pypy/trunk/ Log: A branch to experiment with loading of CPython extension modules From xoraxax at codespeak.net Mon Mar 22 19:54:15 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 19:54:15 +0100 (CET) Subject: [pypy-svn] r72589 - pypy/branch/cpython-extension/pypy/interpreter Message-ID: <20100322185415.D5038282BAD@codespeak.net> Author: xoraxax Date: Mon Mar 22 19:54:14 2010 New Revision: 72589 Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py Log: Reapplied r72583. Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/typedef.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/typedef.py Mon Mar 22 19:54:14 2010 @@ -301,7 +301,10 @@ # ____________________________________________________________ -def make_descr_typecheck_wrapper(func, extraargs=(), cls=None): +def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, cpy_property=False): + extra_arg = "" + if cpy_property: + extra_arg = "property, " if func is None: return None if cls is None: @@ -318,12 +321,12 @@ #print " value Read the value of the property of the given obj.""" @@ -400,7 +405,10 @@ return space.wrap(property) else: try: - return property.fget(space, w_obj) + if property.cpy_property: + return property.fget(property, space, w_obj) + else: + return property.fget(space, w_obj) except DescrMismatch, e: return w_obj.descr_call_mismatch(space, '__getattribute__',\ property.reqcls, Arguments(space, [w_obj, @@ -414,7 +422,10 @@ raise OperationError(space.w_TypeError, space.wrap("readonly attribute")) try: - fset(space, w_obj, w_value) + if property.cpy_property: + fset(property, space, w_obj, w_value) + else: + fset(space, w_obj, w_value) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__setattr__',\ property.reqcls, Arguments(space, [w_obj, @@ -428,7 +439,10 @@ raise OperationError(space.w_AttributeError, space.wrap("cannot delete attribute")) try: - fdel(space, w_obj) + if property.cpy_property: + fdel(space, w_obj) + else: + fdel(property, space, w_obj) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__delattr__',\ property.reqcls, Arguments(space, [w_obj, From arigo at codespeak.net Mon Mar 22 20:08:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 20:08:06 +0100 (CET) Subject: [pypy-svn] r72590 - in pypy/trunk/pypy/translator/c: . src Message-ID: <20100322190806.0736D282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 20:08:05 2010 New Revision: 72590 Modified: pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/src/exception.h Log: More workarounds for the py lib's BuiltinAssertionError. Shows a test failure on CPython 2.6 in test_exception.py. Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Mon Mar 22 20:08:05 2010 @@ -928,9 +928,10 @@ import types, py if isinstance(value, (type, types.ClassType)): if (issubclass(value, BaseException) and - (value.__module__ == 'exceptions' - or value is py.code._AssertionError)): + value.__module__ == 'exceptions'): return 'PyExc_' + value.__name__ + if value is py.code._AssertionError: + return 'PyExc_AssertionError' raise Exception("don't know how to simply render py object: %r" % (value, )) Modified: pypy/trunk/pypy/translator/c/src/exception.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/exception.h (original) +++ pypy/trunk/pypy/translator/c/src/exception.h Mon Mar 22 20:08:05 2010 @@ -99,14 +99,18 @@ assert(RPyExceptionOccurred()); assert(!PyErr_Occurred()); clsname = RPyFetchExceptionType()->ov_name->items; - pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); - if (pycls != NULL && PyExceptionClass_Check(pycls) && - PyObject_IsSubclass(pycls, PyExc_Exception)) { - v = NULL; + v = NULL; + if (strcmp(clsname, "AssertionError") == 0) { + /* workaround against the py lib's BuiltinAssertionError */ + pycls = PyExc_AssertionError; } else { - pycls = PyExc_Exception; /* XXX RPythonError */ - v = PyString_FromString(clsname); + pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); + if (pycls == NULL || !PyExceptionClass_Check(pycls) || + !PyObject_IsSubclass(pycls, PyExc_Exception)) { + pycls = PyExc_Exception; /* XXX RPythonError */ + v = PyString_FromString(clsname); + } } Py_INCREF(pycls); tb = NULL; From arigo at codespeak.net Mon Mar 22 20:11:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 20:11:34 +0100 (CET) Subject: [pypy-svn] r72591 - pypy/trunk/pypy/translator/c/test Message-ID: <20100322191134.D063B282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 20:11:33 2010 New Revision: 72591 Modified: pypy/trunk/pypy/translator/c/test/test_exception.py Log: Fix the test, mostly by removing hacks (except one). Modified: pypy/trunk/pypy/translator/c/test/test_exception.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_exception.py (original) +++ pypy/trunk/pypy/translator/c/test/test_exception.py Mon Mar 22 20:11:33 2010 @@ -121,30 +121,16 @@ def testfn(n): assert n >= 0 - # big confusion with py.test's AssertionError handling here... - # some hacks to try to disable it for the current test. - saved = no_magic() - try: - f1 = getcompiled(testfn, [int]) - res = f1(0) - assert res is None, repr(res) - res = f1(42) - assert res is None, repr(res) - py.test.raises(AssertionError, f1, -2) - finally: - restore_magic(saved) - -def no_magic(): - import __builtin__ - try: - py.magic.revert(__builtin__, 'AssertionError') - return True - except ValueError: - return False - -def restore_magic(saved): - if saved: - py.magic.invoke(assertion=True) + f1 = getcompiled(testfn, [int]) + res = f1(0) + assert res is None, repr(res) + res = f1(42) + assert res is None, repr(res) + e = py.test.raises(Exception, f1, -2) + assert e.type.__name__ == 'AssertionError' + # ^^^ indirection, because we really want + # the original AssertionError and not the + # one patched by the py lib def test_reraise_exception(): From arigo at codespeak.net Mon Mar 22 20:22:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 20:22:16 +0100 (CET) Subject: [pypy-svn] r72592 - pypy/trunk/pypy/translator/jvm/test Message-ID: <20100322192216.96C50282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 20:22:15 2010 New Revision: 72592 Modified: pypy/trunk/pypy/translator/jvm/test/test_backendopt.py pypy/trunk/pypy/translator/jvm/test/test_rarithmetic.py Log: Add two missing skips. Note that we can figure out if there are enough of them by running "py.test --javac=foobar", but I'm a bit unsure about whether to write that in a test... Modified: pypy/trunk/pypy/translator/jvm/test/test_backendopt.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/test/test_backendopt.py (original) +++ pypy/trunk/pypy/translator/jvm/test/test_backendopt.py Mon Mar 22 20:22:15 2010 @@ -1,9 +1,11 @@ import py from pypy.translator.jvm.test.runtest import JvmTest +from pypy.translator.jvm.genjvm import detect_missing_support_programs from pypy.translator.oosupport.test_template.backendopt import BaseTestOptimizedSwitch class TestOptimizedSwitch(BaseTestOptimizedSwitch): def getcompiled(self, fn, annotation): + detect_missing_support_programs() t = JvmTest() return t.compile(fn, None, annotation, backendopt=True) Modified: pypy/trunk/pypy/translator/jvm/test/test_rarithmetic.py ============================================================================== --- pypy/trunk/pypy/translator/jvm/test/test_rarithmetic.py (original) +++ pypy/trunk/pypy/translator/jvm/test/test_rarithmetic.py Mon Mar 22 20:22:15 2010 @@ -1,5 +1,6 @@ import py from pypy.translator.jvm.test.runtest import JvmTest +from pypy.translator.jvm.genjvm import detect_missing_support_programs from pypy.rlib.test.test_rarithmetic import Test_r_uint as BaseTest_r_uint from pypy.rlib.test.test_rarithmetic import Test_r_int as BaseTest_r_int from pypy.rlib.test.test_rarithmetic import test_ovfcheck as base_test_ovfcheck @@ -8,6 +9,7 @@ class BaseAdaptedTest(JvmTest): def unary_test(self, f): + detect_missing_support_programs() cache = {} def new_func(x): xtype = type(x) @@ -20,6 +22,7 @@ super(BaseAdaptedTest,self).unary_test(new_func) def binary_test(self, f, rargs = None): + detect_missing_support_programs() cache = {} def new_func(x, y): if type(x) == self.RTYPE or type(y) == self.RTYPE: From arigo at codespeak.net Mon Mar 22 20:33:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Mar 2010 20:33:59 +0100 (CET) Subject: [pypy-svn] r72595 - pypy/branch/fix-64/pypy/rpython/memory/test Message-ID: <20100322193359.47577282BAD@codespeak.net> Author: arigo Date: Mon Mar 22 20:33:57 2010 New Revision: 72595 Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Log: Fix. Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Mon Mar 22 20:33:57 2010 @@ -687,7 +687,7 @@ def f(): from pypy.rpython.lltypesystem import rffi alist = [A() for i in range(50)] - idarray = lltype.malloc(rffi.INTP.TO, len(alist), flavor='raw') + idarray = lltype.malloc(rffi.LONGP.TO, len(alist), flavor='raw') # Compute the id of all the elements of the list. The goal is # to not allocate memory, so that if the GC needs memory to # remember the ids, it will trigger some collections itself From benjamin at codespeak.net Mon Mar 22 23:17:38 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 22 Mar 2010 23:17:38 +0100 (CET) Subject: [pypy-svn] r72598 - pypy/trunk/pypy/translator/platform Message-ID: <20100322221738.DB34D282BD4@codespeak.net> Author: benjamin Date: Mon Mar 22 23:17:37 2010 New Revision: 72598 Modified: pypy/trunk/pypy/translator/platform/linux.py pypy/trunk/pypy/translator/platform/posix.py Log: (ronny, benjamin) use pkg-config to find libffi on linux Modified: pypy/trunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/trunk/pypy/translator/platform/linux.py (original) +++ pypy/trunk/pypy/translator/platform/linux.py Mon Mar 22 23:17:37 2010 @@ -19,10 +19,12 @@ return ['-shared'] + args def include_dirs_for_libffi(self): - return ['/usr/include/libffi'] + return self._pkg_config("libffi", "--cflags-only-I", + ['/usr/include/libffi']) def library_dirs_for_libffi(self): - return ['/usr/lib/libffi'] + return self._pkg_config("libffi", "--libs-only-L", + ['/usr/lib/libffi']) def library_dirs_for_libffi_a(self): # places where we need to look for libffi.a Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Mon Mar 22 23:17:37 2010 @@ -47,6 +47,13 @@ # hook for maemo return include_dirs + def _pkg_config(self, lib, opt, default): + ret, out, err = _run_subprocess("pkg-config", [lib, opt]) + if ret: + return default + # strip compiler flags + return [entry[2:] for entry in out.split()] + 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 benjamin at codespeak.net Mon Mar 22 23:25:48 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 22 Mar 2010 23:25:48 +0100 (CET) Subject: [pypy-svn] r72599 - in pypy/trunk/pypy/translator/platform: . test Message-ID: <20100322222548.E7014282BD4@codespeak.net> Author: benjamin Date: Mon Mar 22 23:25:47 2010 New Revision: 72599 Modified: pypy/trunk/pypy/translator/platform/linux.py pypy/trunk/pypy/translator/platform/maemo.py pypy/trunk/pypy/translator/platform/test/test_makefile.py Log: kill imports Modified: pypy/trunk/pypy/translator/platform/linux.py ============================================================================== --- pypy/trunk/pypy/translator/platform/linux.py (original) +++ pypy/trunk/pypy/translator/platform/linux.py Mon Mar 22 23:25:47 2010 @@ -1,9 +1,7 @@ import py, os -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 +from pypy.translator.platform import _run_subprocess +from pypy.translator.platform.posix import BasePosix class Linux(BasePosix): name = "linux" Modified: pypy/trunk/pypy/translator/platform/maemo.py ============================================================================== --- pypy/trunk/pypy/translator/platform/maemo.py (original) +++ pypy/trunk/pypy/translator/platform/maemo.py Mon Mar 22 23:25:47 2010 @@ -1,5 +1,6 @@ import py, os -from pypy.translator.platform.linux import Linux, _run_subprocess, GnuMakefile +from pypy.translator.platform.linux import Linux +from pypy.translator.platform.posix import _run_subprocess, GnuMakefile from pypy.translator.platform import ExecutionResult, log from pypy.tool.udir import udir from pypy.tool import autopath Modified: pypy/trunk/pypy/translator/platform/test/test_makefile.py ============================================================================== --- pypy/trunk/pypy/translator/platform/test/test_makefile.py (original) +++ pypy/trunk/pypy/translator/platform/test/test_makefile.py Mon Mar 22 23:25:47 2010 @@ -1,5 +1,5 @@ -from pypy.translator.platform.linux import GnuMakefile as Makefile +from pypy.translator.platform.posix import GnuMakefile as Makefile from StringIO import StringIO import re From xoraxax at codespeak.net Mon Mar 22 23:39:28 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 22 Mar 2010 23:39:28 +0100 (CET) Subject: [pypy-svn] r72600 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100322223928.1148D282BD4@codespeak.net> Author: xoraxax Date: Mon Mar 22 23:39:26 2010 New Revision: 72600 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Finish support for methods and functions. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Mon Mar 22 23:39:26 2010 @@ -2,8 +2,9 @@ from pypy.interpreter.typedef import TypeDef from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments +from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.function import BuiltinFunction, descr_function_get +from pypy.interpreter.function import BuiltinFunction, Method from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ InvalidPointerException, make_ref @@ -62,9 +63,17 @@ class W_PyCMethodObject(W_PyCFunctionObject): w_self = None - def __init__(self, space, ml): + def __init__(self, space, ml, pto): self.space = space self.ml = ml + self.name = rffi.charp2str(ml.c_ml_name) + self.w_objclass = from_ref(space, pto) + + def __repr__(self): + return "method %r of %r objects" % (self.name, self.w_objclass.getname(self.space, '?')) + + def descr_method_repr(self): + return self.space.wrap(self.__repr__()) @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -72,7 +81,6 @@ self = space.interp_w(W_PyCFunctionObject, w_self) w_tuple = __args__.unpack_cpy() ret = self.call(None, w_tuple) - # XXX result.decref() return ret @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -81,20 +89,33 @@ w_tuple = __args__.unpack_cpy(1) w_self = __args__.arguments_w[0] ret = self.call(w_self, w_tuple) - # XXX result.decref() return ret +def cmethod_descr_get(space, w_function, w_obj, w_cls=None): + """functionobject.__get__(obj[, type]) -> method""" + # this is not defined as a method on Function because it's generally + # useful logic: w_function can be any callable. It is used by Method too. + asking_for_bound = (space.is_w(w_cls, space.w_None) or + not space.is_w(w_obj, space.w_None) or + space.is_w(w_cls, space.type(space.w_None))) + if asking_for_bound: + return space.wrap(Method(space, w_function, w_obj, w_cls)) + else: + return w_function + W_PyCFunctionObject.typedef = TypeDef( - 'builtin_function', + 'builtin_function_or_method', __call__ = interp2app(cfunction_descr_call), - __get__ = interp2app(descr_function_get), ) W_PyCMethodObject.typedef = TypeDef( - 'builtin_method', - __get__ = interp2app(descr_function_get), + 'method', + __get__ = interp2app(cmethod_descr_get), __call__ = interp2app(cmethod_descr_call), + __name__ = interp_attrproperty('name', cls=W_PyCMethodObject), + __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCMethodObject), + __repr__ = interp2app(W_PyCMethodObject.descr_method_repr), ) @@ -103,5 +124,5 @@ def PyDescr_NewMethod(space, pto, method): - return space.wrap(W_PyCMethodObject(space, method)) + return space.wrap(W_PyCMethodObject(space, method, pto)) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py Mon Mar 22 23:39:26 2010 @@ -15,5 +15,7 @@ print "type of obj has type", type(type(obj)) obj2 = obj.copy() assert module.new().name == "Foo Example" - skip("In progress") + c = module.fooType.copy + assert not "im_func" in dir(module.fooType.copy) + assert module.fooType.copy.__objclass__ is module.fooType assert "copy" in repr(module.fooType.copy) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 22 23:39:26 2010 @@ -217,12 +217,6 @@ # XXX fill slots in pto return pto -def create_type_object(space, pto): - w_type = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) - w_type.__init__(space, pto) - w_type.ready() - return w_type - @cpython_api_c() def PyType_Ready(space, pto): "Implemented in typeobject.c" @@ -232,9 +226,12 @@ state = space.fromcache(State) ptr = ctypes.addressof(pto._obj._storage) if ptr not in state.py_objects_r2w: - w_obj = create_type_object(space, pto) + w_obj = space.allocate_instance(W_PyCTypeObject, + space.gettypeobject(W_PyCTypeObject.typedef)) state.py_objects_r2w[ptr] = w_obj state.py_objects_w2r[w_obj] = pto + w_obj.__init__(space, pto) + w_obj.ready() return 1 W_PyCObject.typedef = W_ObjectObject.typedef From afa at codespeak.net Tue Mar 23 00:00:41 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 00:00:41 +0100 (CET) Subject: [pypy-svn] r72601 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100322230041.8662A282BD4@codespeak.net> Author: afa Date: Tue Mar 23 00:00:40 2010 New Revision: 72601 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: compatibility with CPython 2.4 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 00:00:40 2010 @@ -119,7 +119,7 @@ for i in xrange(size - rffi.sizeof(T)): new_fields.append(("custom%i" % (i, ), lltype.Char)) hints["padding"] = hints["padding"] + tuple(pad_fields) - return lltype.Struct(hints["c_name"], *new_fields, hints=hints) + return lltype.Struct(hints["c_name"], hints=hints, *new_fields) def make_ref(space, w_obj, borrowed=False): if w_obj is None: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 23 00:00:40 2010 @@ -21,7 +21,7 @@ def PyPy_Crash2(space): 1/0 -class TestApi(): +class TestApi: def test_signature(self): assert 'Py_InitModule' in api.FUNCTIONS assert api.FUNCTIONS['Py_InitModule'].argtypes == [ From arigo at codespeak.net Tue Mar 23 00:48:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 00:48:05 +0100 (CET) Subject: [pypy-svn] r72602 - in pypy/branch/fix-64/pypy/translator/c: . src test Message-ID: <20100322234805.830DB282BD4@codespeak.net> Author: arigo Date: Tue Mar 23 00:48:03 2010 New Revision: 72602 Modified: pypy/branch/fix-64/pypy/translator/c/node.py pypy/branch/fix-64/pypy/translator/c/primitive.py pypy/branch/fix-64/pypy/translator/c/src/llgroup.h pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py Log: Drop the fragile implementation assuming we are in the 32-bit part of the 64-bit address space. Just do the same as we do in the 32-bit mode (but still a bit more efficient: we have a whole 32 bits, so no need for *4 or *8 nor loading a short). Modified: pypy/branch/fix-64/pypy/translator/c/node.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/node.py (original) +++ pypy/branch/fix-64/pypy/translator/c/node.py Tue Mar 23 00:48:03 2010 @@ -989,18 +989,13 @@ forward_cdecl(ctype, self.name, self.db.standalone, self.is_thread_local())) yield '#include "src/llgroup.h"' + yield 'PYPY_GROUP_CHECK_SIZE(%s)' % (self.name,) for i, member in enumerate(self.obj.members): structnode = self.db.getcontainernode(member) yield '#define %s %s.member%d' % (structnode.name, self.name, i) yield '' - def startupcode(self): - count = len(self.obj.members) - if count == 0: - return [] - return ['PYPY_GROUP_CHECK_SIZE(%s, member%d);' % (self.name, count-1)] - def initializationexpr(self): self._fix_members() lines = ['{'] Modified: pypy/branch/fix-64/pypy/translator/c/primitive.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/primitive.py (original) +++ pypy/branch/fix-64/pypy/translator/c/primitive.py Tue Mar 23 00:48:03 2010 @@ -146,9 +146,8 @@ if isinstance(value, Symbolic): if isinstance(value, llgroup.GroupMemberOffset): groupnode = db.getcontainernode(value.grpptr._as_obj()) - return 'GROUP_MEMBER_OFFSET(%s, %s, member%s)' % ( + return 'GROUP_MEMBER_OFFSET(%s, member%s)' % ( cdecl(groupnode.implementationtypename, ''), - groupnode.name, value.index, ) else: Modified: pypy/branch/fix-64/pypy/translator/c/src/llgroup.h ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/src/llgroup.h (original) +++ pypy/branch/fix-64/pypy/translator/c/src/llgroup.h Tue Mar 23 00:48:03 2010 @@ -11,7 +11,7 @@ typedef unsigned short pypy_halfword_t; -#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ +#define GROUP_MEMBER_OFFSET(grouptype, membername) \ ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 4)) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ @@ -22,33 +22,31 @@ /* A macro to crash at compile-time if sizeof(group) is too large. Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - { typedef char group_##groupname##_is_too_large[ \ - 2*(sizeof(groupname) <= 65536*4)-1]; } +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 65536*4)-1]; #else /******************************************************/ /* On 64-bit platforms, a CombinedSymbolic is two UINTs, and the lower - one stores a real pointer to the group memeber. The limitation is - that this pointer must fit inside 32-bit, i.e. the whole group must - be located in the first 32 bits of address space. */ + one is an 32-bit offset from the start of the group. */ typedef unsigned int pypy_halfword_t; -#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ - ((long)(&groupname.membername)) +#define GROUP_MEMBER_OFFSET(grouptype, membername) \ + offsetof(grouptype, membername) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ - ((long)compactoffset) + (((char*)groupptr) + (long)compactoffset) #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ - ((long)compactoffset + skipoffset) + (((char*)groupptr) + skipoffset + (long)compactoffset) -/* A macro to check at run-time if the group is below the 32-bit limit. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - if ((unsigned long)(&groupname.lastname) > 0xFFFFFFFF) \ - error = "group " #groupname " is not located in the " \ - "initial 32 bits of address space" +/* A macro to crash at compile-time if sizeof(group) is too large. + Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 4294967296L)-1]; #endif /*****************************************************/ Modified: pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py Tue Mar 23 00:48:03 2010 @@ -732,14 +732,17 @@ ('z4', Signed), ('u4', Signed)) goffsets = [] for i in range(4096 + toobig): - goffsets.append(grp.add_member(malloc(S1, immortal=True))) + ofs = grp.add_member(malloc(S1, immortal=True)) + goffsets.append(llgroup.CombinedSymbolic(ofs, 0)) grpptr = grp._as_ptr() def f(n): - p = llop.get_group_member(Ptr(S1), grpptr, goffsets[n]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[n]) + p = llop.get_group_member(Ptr(S1), grpptr, o) p.x = 5 for i in range(len(goffsets)): if i != n: - q = llop.get_group_member(Ptr(S1), grpptr, goffsets[i]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[i]) + q = llop.get_group_member(Ptr(S1), grpptr, o) q.x = 666 return p.x if toobig: From xoraxax at codespeak.net Tue Mar 23 01:52:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 01:52:20 +0100 (CET) Subject: [pypy-svn] r72603 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100323005220.511B2282BD4@codespeak.net> Author: xoraxax Date: Tue Mar 23 01:52:18 2010 New Revision: 72603 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Reworked memory handling, please review. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 01:52:18 2010 @@ -45,16 +45,17 @@ class ApiFunction: - def __init__(self, argtypes, restype, callable, borrowed): + def __init__(self, argtypes, restype, callable, borrowed, dont_deref): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) self.callable = callable self.borrowed = borrowed + self.dont_deref = dont_deref -def cpython_api(argtypes, restype, borrowed=False): +def cpython_api(argtypes, restype, borrowed=False, dont_deref=False): def decorate(func): - api_function = ApiFunction(argtypes, restype, func, borrowed) + api_function = ApiFunction(argtypes, restype, func, borrowed, dont_deref) FUNCTIONS[func.func_name] = api_function func.api_func = api_function return func @@ -177,6 +178,47 @@ w_obj_type = space.type(w_obj) return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) +def make_wrapper(space, callable): + def wrapper(*args): + boxed_args = [] + # XXX use unrolling_iterable here + print >>sys.stderr, callable, + for i, typ in enumerate(callable.api_func.argtypes): + arg = args[i] + if typ is PyObject and not callable.api_func.dont_deref: + arg = from_ref(space, arg) + boxed_args.append(arg) + state = space.fromcache(State) + try: + retval = callable(space, *boxed_args) + print >>sys.stderr, " DONE" + except OperationError, e: + e.normalize_exception(space) + state.exc_type = e.w_type + state.exc_value = e.get_w_value(space) + except BaseException, e: + state.exc_type = space.w_SystemError + state.exc_value = space.wrap(str(e)) + import traceback + traceback.print_exc() + + if state.exc_value is not None: + restype = callable.api_func.restype + if restype is lltype.Void: + return + if restype is PyObject: + return lltype.nullptr(PyObject.TO) + if restype in (Py_ssize_t, rffi.INT_real): + return rffi.cast(restype, -1) + assert False, "Unknown return type" + + if callable.api_func.restype is PyObject: + retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) + if callable.api_func.restype is rffi.INT_real: + retval = rffi.cast(rffi.INT_real, retval) + return retval + return wrapper + #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions @@ -279,51 +321,11 @@ ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), ctypes.c_void_p).value - def make_wrapper(callable): - def wrapper(*args): - boxed_args = [] - # XXX use unrolling_iterable here - print >>sys.stderr, callable, - for i, typ in enumerate(callable.api_func.argtypes): - arg = args[i] - if typ is PyObject: - arg = from_ref(space, arg) - boxed_args.append(arg) - state = space.fromcache(State) - try: - retval = callable(space, *boxed_args) - print >>sys.stderr, " DONE" - except OperationError, e: - e.normalize_exception(space) - state.exc_type = e.w_type - state.exc_value = e.get_w_value(space) - except BaseException, e: - state.exc_type = space.w_SystemError - state.exc_value = space.wrap(str(e)) - import traceback - traceback.print_exc() - - if state.exc_value is not None: - restype = callable.api_func.restype - if restype is lltype.Void: - return - if restype is PyObject: - return lltype.nullptr(PyObject.TO) - if restype in (Py_ssize_t, rffi.INT_real): - return rffi.cast(restype, -1) - assert False, "Unknown return type" - - if callable.api_func.restype is PyObject: - retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) - if callable.api_func.restype is rffi.INT_real: - retval = rffi.cast(rffi.INT_real, retval) - return retval - return wrapper - # implement structure initialization code for name, func in FUNCTIONS.iteritems(): pypyAPI[structindex[name]] = ctypes.cast( - ll2ctypes.lltype2ctypes(llhelper(func.functype, make_wrapper(func.callable))), + ll2ctypes.lltype2ctypes(llhelper(func.functype, + make_wrapper(space, func.callable))), ctypes.c_void_p) return modulename.new(ext='') Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Tue Mar 23 01:52:18 2010 @@ -7,15 +7,15 @@ # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, w_obj): + print "DECREF", w_obj state = space.fromcache(State) obj = state.py_objects_w2r[w_obj] obj.c_obj_refcnt -= 1 if obj.c_obj_refcnt == 0: - del state.py_objects_w2r[w_obj] ptr = ctypes.addressof(obj._obj._storage) + _Py_Dealloc(space, w_obj) + del state.py_objects_w2r[w_obj] del state.py_objects_r2w[ptr] - # XXX this will likely be somewhere else when we have grown a type object - lltype.free(obj, flavor='raw') else: assert obj.c_obj_refcnt > 0 return @@ -26,3 +26,19 @@ obj = state.py_objects_w2r.get(w_obj) obj.c_obj_refcnt += 1 + +def _Py_Dealloc(space, w_obj): + from pypy.module.cpyext.typeobject import PyTypeObjectPtr + from pypy.module.cpyext.methodobject import generic_cpy_call + state = space.fromcache(State) + w_type = space.type(w_obj) + pto = make_ref(space, w_type) + pto = rffi.cast(PyTypeObjectPtr, pto) + try: + print "Calling ", pto.c_tp_dealloc, "of", w_obj, "'s type which is", w_type + generic_cpy_call(space, pto.c_tp_dealloc, w_obj, decref_args=False) + finally: + # XXX uncommenting the next line gives double frees, why? + #Py_DECREF(space, w_type) # make_ref bumps refcount + pass + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Tue Mar 23 01:52:18 2010 @@ -28,7 +28,9 @@ raise return ret -def generic_cpy_call(space, func, *args): +def generic_cpy_call(space, func, *args, **kwargs): + decref_args = kwargs.pop("decref_args", False) + assert not decref_args boxed_args = [] for arg in args: # XXX ur needed if isinstance(arg, W_Root) or arg is None: @@ -37,13 +39,16 @@ boxed_args.append(arg) result = func(*boxed_args) try: - ret = from_ref_ex(space, result) - Py_DECREF(space, ret) - return ret + FT = lltype.typeOf(func).TO + if FT.RESULT is not lltype.Void: + ret = from_ref_ex(space, result) + Py_DECREF(space, ret) + return ret finally: - for arg in args: # XXX ur needed - if arg is not None and isinstance(arg, W_Root): - Py_DECREF(space, arg) + if decref_args: + for arg in args: # XXX ur needed + if arg is not None and isinstance(arg, W_Root): + Py_DECREF(space, arg) # XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Tue Mar 23 01:52:18 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref +from pypy.module.cpyext.state import State from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject @@ -8,9 +9,17 @@ def _PyObject_New(space, w_type): if isinstance(w_type, W_PyCTypeObject): w_pycobj = space.allocate_instance(W_PyCObject, w_type) + w_pycobj.__init__(space) return w_pycobj assert False, "Please add more cases in get_cls_for_type_object!" @cpython_api([rffi.VOIDP_real], lltype.Void) -def PyObject_Del(space, w_obj): - pass # XXX move lltype.free here +def PyObject_Del(space, obj): + # XXX cast object according to the basesize in pto + lltype.free(obj, flavor='raw') + + at cpython_api([PyObject], lltype.Void, dont_deref=True) +def PyObject_Del_cast(space, obj): + # XXX cast object according to the basesize in pto + lltype.free(obj, flavor='raw') + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 23 01:52:18 2010 @@ -117,7 +117,6 @@ self.space.wrap('foo')) self.space.delitem(self.space.sys.get('modules'), self.space.wrap('foo')) - Py_DECREF(self.space, w_mod) except OperationError: pass self.space.fromcache(State).print_refcounts() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Tue Mar 23 01:52:18 2010 @@ -2,6 +2,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void +from pypy.rpython.annlowlevel import llhelper from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable @@ -11,6 +12,7 @@ from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY +from pypy.module.cpyext.api import make_wrapper from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State @@ -204,16 +206,25 @@ bases_w or [space.w_object], dict_w) class W_PyCObject(Wrappable): - pass + def __init__(self, space): + self.space = space + + def __del__(self): + space = self.space + self.clear_all_weakrefs() + w_type = space.type(self) + assert isinstance(w_type, W_PyCTypeObject) + pto = w_type.pto + generic_cpy_call(space, pto.c_tp_dealloc, self) - at unwrap_spec(ObjSpace, W_Root, W_Root) -def cobject_descr_getattr(space, w_obj, w_name): - name = space.str_w(w_name) - return w_name def allocate_type_obj(space, w_obj): + from pypy.module.cpyext.object import PyObject_Del_cast pto = lltype.malloc(PyTypeObject, None, flavor="raw") + callable = PyObject_Del_cast + pto.c_tp_dealloc = llhelper(callable.api_func.functype, + make_wrapper(space, callable)) # XXX fill slots in pto return pto From xoraxax at codespeak.net Tue Mar 23 02:21:35 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 02:21:35 +0100 (CET) Subject: [pypy-svn] r72604 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323012135.1E824282BD4@codespeak.net> Author: xoraxax Date: Tue Mar 23 02:21:33 2010 New Revision: 72604 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO Log: Updated todo items. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Tue Mar 23 02:21:33 2010 @@ -1,6 +1,6 @@ - - Make the pypy interpreter support dynamically created typeobjects to support PyTypeObject - - Add exceptions - Generate header files programmatically. + - Implement C API. + - Complete the PyTypeObject initialization code. PyStringObject support ====================== From xoraxax at codespeak.net Tue Mar 23 02:22:07 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 02:22:07 +0100 (CET) Subject: [pypy-svn] r72605 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323012207.D93BC282BD4@codespeak.net> Author: xoraxax Date: Tue Mar 23 02:22:06 2010 New Revision: 72605 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Also set free func. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Tue Mar 23 02:22:06 2010 @@ -30,9 +30,9 @@ PyNumberMethods = PySequenceMethods = PyMappingMethods = \ PyBufferProcs = PyMemberDef = rffi.VOIDP.TO -freefunc = P(FT([rffi.VOIDP], Void)) +freefunc = P(FT([rffi.VOIDP_real], Void)) destructor = P(FT([PyO], Void)) -printfunc = P(FT([PyO, rffi.VOIDP, rffi.INT_real], rffi.INT)) +printfunc = P(FT([PyO, rffi.VOIDP_real, rffi.INT_real], rffi.INT)) getattrfunc = P(FT([PyO, rffi.CCHARP], PyO)) getattrofunc = P(FT([PyO, PyO], PyO)) setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT_real)) @@ -65,8 +65,8 @@ objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) objobjproc = P(FT([PyO, PyO], rffi.INT_real)) -visitproc = P(FT([PyO, rffi.VOIDP], rffi.INT_real)) -traverseproc = P(FT([PyO, visitproc, rffi.VOIDP], rffi.INT_real)) +visitproc = P(FT([PyO, rffi.VOIDP_real], rffi.INT_real)) +traverseproc = P(FT([PyO, visitproc, rffi.VOIDP_real], rffi.INT_real)) getter = P(FT([PyO, rffi.VOIDP_real], PyO)) setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real)) @@ -220,11 +220,14 @@ def allocate_type_obj(space, w_obj): - from pypy.module.cpyext.object import PyObject_Del_cast + from pypy.module.cpyext.object import PyObject_Del_cast, PyObject_Del pto = lltype.malloc(PyTypeObject, None, flavor="raw") callable = PyObject_Del_cast pto.c_tp_dealloc = llhelper(callable.api_func.functype, make_wrapper(space, callable)) + callable = PyObject_Del + pto.c_tp_free = llhelper(callable.api_func.functype, + make_wrapper(space, callable)) # XXX fill slots in pto return pto From xoraxax at codespeak.net Tue Mar 23 02:23:27 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 02:23:27 +0100 (CET) Subject: [pypy-svn] r72606 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323012327.C00F6282BD4@codespeak.net> Author: xoraxax Date: Tue Mar 23 02:23:26 2010 New Revision: 72606 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Fill the type field. Unfortunately, we cannot easily fill it lazily because Py_TYPE needs to remain a macro. Maybe the macro could force the type obj? But then refcounting is hard. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 02:23:26 2010 @@ -132,8 +132,13 @@ if py_obj is None: from pypy.module.cpyext.typeobject import allocate_type_obj,\ W_PyCTypeObject, W_PyCObject - if space.is_w(space.type(w_obj), space.w_type): + w_type = space.type(w_obj) + if space.is_w(w_type, space.w_type): py_obj = allocate_type_obj(space, w_obj) + if space.is_w(w_type, w_obj): + pto = py_obj + else: + pto = make_ref(space, w_type) elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) @@ -143,6 +148,8 @@ py_obj = lltype.malloc(T, None, flavor="raw") else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + pto = make_ref(space, space.type(w_obj)) + py_obj.c_obj_type = rffi.cast(PyObject, pto) py_obj.c_obj_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value From xoraxax at codespeak.net Tue Mar 23 02:24:35 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 02:24:35 +0100 (CET) Subject: [pypy-svn] r72607 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323012435.E8E73282BD6@codespeak.net> Author: xoraxax Date: Tue Mar 23 02:24:34 2010 New Revision: 72607 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Now refcounting of type objects works again :-) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Tue Mar 23 02:24:34 2010 @@ -38,7 +38,5 @@ print "Calling ", pto.c_tp_dealloc, "of", w_obj, "'s type which is", w_type generic_cpy_call(space, pto.c_tp_dealloc, w_obj, decref_args=False) finally: - # XXX uncommenting the next line gives double frees, why? - #Py_DECREF(space, w_type) # make_ref bumps refcount - pass + Py_DECREF(space, w_type) # make_ref bumps refcount From xoraxax at codespeak.net Tue Mar 23 02:35:40 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 02:35:40 +0100 (CET) Subject: [pypy-svn] r72608 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323013540.0A1F0282BD6@codespeak.net> Author: xoraxax Date: Tue Mar 23 02:35:39 2010 New Revision: 72608 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Also fill tp_name and tp_basicsize. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Tue Mar 23 02:35:39 2010 @@ -1,6 +1,7 @@ - Generate header files programmatically. - Implement C API. - Complete the PyTypeObject initialization code. + - Free pto.c_tp_name correctly PyStringObject support ====================== Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Tue Mar 23 02:35:39 2010 @@ -219,7 +219,7 @@ -def allocate_type_obj(space, w_obj): +def allocate_type_obj(space, w_type): from pypy.module.cpyext.object import PyObject_Del_cast, PyObject_Del pto = lltype.malloc(PyTypeObject, None, flavor="raw") callable = PyObject_Del_cast @@ -228,6 +228,9 @@ callable = PyObject_Del pto.c_tp_free = llhelper(callable.api_func.functype, make_wrapper(space, callable)) + # XXX free c_tp_name again! + pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) + pto.c_tp_basicsize = -1 # hopefully this makes malloc bail # XXX fill slots in pto return pto @@ -249,10 +252,6 @@ return 1 W_PyCObject.typedef = W_ObjectObject.typedef -#TypeDef( -# 'C_object', -# #__getattrbute__ = interp2app(cobject_descr_getattribute), -# ) W_PyCTypeObject.typedef = TypeDef( 'C_type', W_TypeObject.typedef From afa at codespeak.net Tue Mar 23 08:57:32 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 08:57:32 +0100 (CET) Subject: [pypy-svn] r72609 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323075732.22F45282BD8@codespeak.net> Author: afa Date: Tue Mar 23 08:57:29 2010 New Revision: 72609 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Don't let interp-level exceptions escape Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 08:57:29 2010 @@ -13,7 +13,7 @@ from pypy.tool.udir import udir from pypy.translator import platform from pypy.module.cpyext.state import State -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, unwrap_spec @@ -341,9 +341,21 @@ def load_extension_module(space, path, name): state = space.fromcache(State) from pypy.rlib import libffi - dll = libffi.CDLL(path) - initfunc = dll.getpointer( - 'init%s' % (name,), [], libffi.ffi_type_void) + try: + dll = libffi.CDLL(path) + except libffi.DLOpenError: + raise operationerrfmt( + space.w_ImportError, + "unable to load extension module %s", + path) + try: + initfunc = dll.getpointer( + 'init%s' % (name,), [], libffi.ffi_type_void) + except KeyError: + raise operationerrfmt( + space.w_ImportError, + "function init%s not found in library %s", + name, path) dll.unload_on_finalization = False initfunc.call(lltype.Void) state.check_and_raise_exception() From afa at codespeak.net Tue Mar 23 11:48:51 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 11:48:51 +0100 (CET) Subject: [pypy-svn] r72611 - pypy/branch/cpython-extension/pypy/interpreter Message-ID: <20100323104851.C4F72282BD8@codespeak.net> Author: afa Date: Tue Mar 23 11:48:50 2010 New Revision: 72611 Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py Log: Fix translation of GetSetProperty Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/typedef.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/typedef.py Tue Mar 23 11:48:50 2010 @@ -301,47 +301,57 @@ # ____________________________________________________________ -def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, cpy_property=False): - extra_arg = "" - if cpy_property: - extra_arg = "property, " +def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, use_closure=False): + # - if cls is None, the wrapped object is passed to the function + # - if cls is a class, an unwrapped instance is passed + # - if cls is a string, if func is None: return None - if cls is None: + if cls is None and use_closure: return func if hasattr(func, 'im_func'): assert func.im_class is cls func = func.im_func - + miniglobals = { func.__name__: func, 'OperationError': OperationError } if isinstance(cls, str): + assert 0 #print " value @@ -405,10 +418,7 @@ return space.wrap(property) else: try: - if property.cpy_property: - return property.fget(property, space, w_obj) - else: - return property.fget(space, w_obj) + return property.fget(property, space, w_obj) except DescrMismatch, e: return w_obj.descr_call_mismatch(space, '__getattribute__',\ property.reqcls, Arguments(space, [w_obj, @@ -422,10 +432,7 @@ raise OperationError(space.w_TypeError, space.wrap("readonly attribute")) try: - if property.cpy_property: - fset(property, space, w_obj, w_value) - else: - fset(space, w_obj, w_value) + fset(property, space, w_obj, w_value) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__setattr__',\ property.reqcls, Arguments(space, [w_obj, @@ -439,10 +446,7 @@ raise OperationError(space.w_AttributeError, space.wrap("cannot delete attribute")) try: - if property.cpy_property: - fdel(space, w_obj) - else: - fdel(property, space, w_obj) + fdel(property, space, w_obj) except DescrMismatch, e: w_obj.descr_call_mismatch(space, '__delattr__',\ property.reqcls, Arguments(space, [w_obj, From afa at codespeak.net Tue Mar 23 11:52:00 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 11:52:00 +0100 (CET) Subject: [pypy-svn] r72612 - pypy/branch/cpython-extension/pypy/interpreter Message-ID: <20100323105200.12788282BD8@codespeak.net> Author: afa Date: Tue Mar 23 11:51:58 2010 New Revision: 72612 Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py Log: Who uses GetSetProperty with cls=someString? Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/typedef.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/typedef.py Tue Mar 23 11:51:58 2010 @@ -304,7 +304,7 @@ def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, use_closure=False): # - if cls is None, the wrapped object is passed to the function # - if cls is a class, an unwrapped instance is passed - # - if cls is a string, + # - if cls is a string, XXX unused? if func is None: return None if cls is None and use_closure: @@ -318,7 +318,7 @@ 'OperationError': OperationError } if isinstance(cls, str): - assert 0 + assert 0, "unused?" #print " Author: xoraxax Date: Tue Mar 23 11:53:33 2010 New Revision: 72613 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: Fix kwargs handling of generic_cpy_call, set acceptable_as_base_class correctly. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Tue Mar 23 11:53:33 2010 @@ -29,8 +29,8 @@ return ret def generic_cpy_call(space, func, *args, **kwargs): - decref_args = kwargs.pop("decref_args", False) - assert not decref_args + decref_args = kwargs.pop("decref_args", True) + assert not kwargs boxed_args = [] for arg in args: # XXX ur needed if isinstance(arg, W_Root) or arg is None: @@ -52,7 +52,6 @@ # XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): - acceptable_as_base_class = False def __init__(self, space, ml, w_self): self.space = space self.ml = ml @@ -114,6 +113,8 @@ __call__ = interp2app(cfunction_descr_call), ) +W_PyCFunctionObject.typedef.acceptable_as_base_class = False + W_PyCMethodObject.typedef = TypeDef( 'method', __get__ = interp2app(cmethod_descr_get), @@ -123,6 +124,7 @@ __repr__ = interp2app(W_PyCMethodObject.descr_method_repr), ) +W_PyCMethodObject.typedef.acceptable_as_base_class = False def PyCFunction_NewEx(space, ml, w_self): # not directly the API sig return space.wrap(W_PyCFunctionObject(space, ml, w_self)) From xoraxax at codespeak.net Tue Mar 23 11:53:59 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 11:53:59 +0100 (CET) Subject: [pypy-svn] r72614 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323105359.D4051282BD8@codespeak.net> Author: xoraxax Date: Tue Mar 23 11:53:58 2010 New Revision: 72614 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Only borrow the type references that we set into the type field. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 11:53:58 2010 @@ -138,7 +138,7 @@ if space.is_w(w_type, w_obj): pto = py_obj else: - pto = make_ref(space, w_type) + pto = make_ref(space, w_type, borrowed=True) elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) @@ -148,7 +148,7 @@ py_obj = lltype.malloc(T, None, flavor="raw") else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") - pto = make_ref(space, space.type(w_obj)) + pto = make_ref(space, space.type(w_obj), borrowed=True) py_obj.c_obj_type = rffi.cast(PyObject, pto) py_obj.c_obj_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) From afa at codespeak.net Tue Mar 23 13:17:23 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 13:17:23 +0100 (CET) Subject: [pypy-svn] r72615 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100323121723.535C0282BD8@codespeak.net> Author: afa Date: Tue Mar 23 13:17:21 2010 New Revision: 72615 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: Fix exception message and add a test --Cette ligne, et les suivantes ci-dessous, seront ignor?es-- M api.py M test/test_cpyext.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 13:17:21 2010 @@ -343,11 +343,11 @@ from pypy.rlib import libffi try: dll = libffi.CDLL(path) - except libffi.DLOpenError: + except libffi.DLOpenError, e: raise operationerrfmt( space.w_ImportError, - "unable to load extension module %s", - path) + "unable to load extension module '%s': %s", + path, e.msg) try: initfunc = dll.getpointer( 'init%s' % (name,), [], libffi.ffi_type_void) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 23 13:17:21 2010 @@ -32,6 +32,17 @@ assert rffi.sizeof(T) == 42 print T +class AppTestApi: + def setup_class(cls): + cls.space = gettestobjspace(usemodules=['cpyext']) + from pypy.rlib.libffi import get_libc_name + cls.w_libc = cls.space.wrap(get_libc_name()) + + def test_load_error(self): + import cpyext + raises(ImportError, cpyext.load_module, "missing.file", "foo") + raises(ImportError, cpyext.load_module, self.libc, "invalid.function") + def compile_module(modname, **kwds): eci = ExternalCompilationInfo( export_symbols=['init%s' % (modname,)], From arigo at codespeak.net Tue Mar 23 13:41:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 13:41:59 +0100 (CET) Subject: [pypy-svn] r72616 - pypy/trunk/pypy/translator/c Message-ID: <20100323124159.15610282BD8@codespeak.net> Author: arigo Date: Tue Mar 23 13:41:58 2010 New Revision: 72616 Modified: pypy/trunk/pypy/translator/c/node.py Log: Oups, fix. Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Tue Mar 23 13:41:58 2010 @@ -227,7 +227,7 @@ return '%s.items[%s]' % (baseexpr, index) access_expr_varindex = access_expr - def ptr_access_expr(self, baseexpr, index): + def ptr_access_expr(self, baseexpr, index, dummy=False): assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,) return self.itemindex_access_expr(baseexpr, index) @@ -325,7 +325,7 @@ return '%s[%d]' % (baseexpr, index) access_expr_varindex = access_expr - def ptr_access_expr(self, baseexpr, index): + def ptr_access_expr(self, baseexpr, index, dummy=False): assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,) return self.itemindex_access_expr(baseexpr, index) @@ -368,7 +368,7 @@ def getptrtype(self): return self.itemtypename.replace('@', '*@') - def access_expr(self, baseexpr, index): + def access_expr(self, baseexpr, index, dummy=False): if not isinstance(index, int): assert index.startswith('item') index = int(index[4:]) From arigo at codespeak.net Tue Mar 23 13:46:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 13:46:17 +0100 (CET) Subject: [pypy-svn] r72617 - pypy/trunk/pypy/translator/platform Message-ID: <20100323124617.A2D1B282BD8@codespeak.net> Author: arigo Date: Tue Mar 23 13:46:16 2010 New Revision: 72617 Modified: pypy/trunk/pypy/translator/platform/posix.py Log: If pkg-config is not installed, don't crash, but just return the default. Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Tue Mar 23 13:46:16 2010 @@ -48,7 +48,10 @@ return include_dirs def _pkg_config(self, lib, opt, default): - ret, out, err = _run_subprocess("pkg-config", [lib, opt]) + try: + ret, out, err = _run_subprocess("pkg-config", [lib, opt]) + except OSError: + ret = 1 if ret: return default # strip compiler flags From arigo at codespeak.net Tue Mar 23 13:47:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 13:47:46 +0100 (CET) Subject: [pypy-svn] r72618 - pypy/trunk/pypy/doc Message-ID: <20100323124746.783AE282BD8@codespeak.net> Author: arigo Date: Tue Mar 23 13:47:45 2010 New Revision: 72618 Modified: pypy/trunk/pypy/doc/getting-started-python.txt Log: List pkg-config as a dependency. Modified: pypy/trunk/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/trunk/pypy/doc/getting-started-python.txt (original) +++ pypy/trunk/pypy/doc/getting-started-python.txt Tue Mar 23 13:47:45 2010 @@ -42,6 +42,7 @@ * ``python-dev`` * ``python-ctypes`` if you are still using Python2.4 * ``libffi-dev`` + * ``pkg-config`` (to help us locate libffi files) * ``libz-dev`` (for the optional ``zlib`` module) * ``libbz2-dev`` (for the optional ``bz2`` module) * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) From arigo at codespeak.net Tue Mar 23 13:57:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 13:57:03 +0100 (CET) Subject: [pypy-svn] r72619 - pypy/trunk/pypy/translator/platform Message-ID: <20100323125703.3E708282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 13:57:01 2010 New Revision: 72619 Modified: pypy/trunk/pypy/translator/platform/__init__.py pypy/trunk/pypy/translator/platform/posix.py Log: Change the current working directory when calling gcc. It helps with obscure issues that might be related to the fact that e.g. our pypy/translator/c directory contains subdirectories called 'src' or 'gcc'. Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Tue Mar 23 13:57:01 2010 @@ -12,7 +12,7 @@ from subprocess import PIPE, Popen -def _run_subprocess(executable, args, env=None): +def _run_subprocess(executable, args, env=None, cwd=None): if isinstance(args, str): args = str(executable) + ' ' + args shell = True @@ -22,7 +22,7 @@ else: args = [str(executable)] + args shell = False - pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env) + pipe = Popen(args, stdout=PIPE, stderr=PIPE, shell=shell, env=env, cwd=cwd) stdout, stderr = pipe.communicate() return pipe.returncode, stdout, stderr @@ -108,9 +108,10 @@ # some helpers which seem to be cross-platform enough - def _execute_c_compiler(self, cc, args, outname): + def _execute_c_compiler(self, cc, args, outname, cwd=None): log.execute(cc + ' ' + ' '.join(args)) - returncode, stdout, stderr = _run_subprocess(cc, args, self.c_environ) + returncode, stdout, stderr = _run_subprocess(cc, args, self.c_environ, + cwd) self._handle_error(returncode, stderr, stdout, outname) def _handle_error(self, returncode, stderr, stdout, outname): Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Tue Mar 23 13:57:01 2010 @@ -32,7 +32,8 @@ 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) + self._execute_c_compiler(cc, args, oname, + cwd=str(cfile.dirpath())) return oname def _link(self, cc, ofiles, link_args, standalone, exe_name): @@ -40,7 +41,8 @@ args += ['-o', str(exe_name)] if not standalone: args = self._args_for_shared(args) - self._execute_c_compiler(cc, args, exe_name) + self._execute_c_compiler(cc, args, exe_name, + cwd=str(exe_name.dirpath())) return exe_name def _preprocess_dirs(self, include_dirs): From afa at codespeak.net Tue Mar 23 14:23:53 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 14:23:53 +0100 (CET) Subject: [pypy-svn] r72620 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100323132353.97E08282BD6@codespeak.net> Author: afa Date: Tue Mar 23 14:23:52 2010 New Revision: 72620 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Log: Avoid the NullPointerException that masks the previous error Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Tue Mar 23 14:23:52 2010 @@ -138,6 +138,7 @@ if (m == NULL) return; d = PyModule_GetDict(m); - PyDict_SetItemString(d, "fooType", (PyObject *)&footype); + if (d) + PyDict_SetItemString(d, "fooType", (PyObject *)&footype); /* No need to check the error here, the caller will do that */ } From afa at codespeak.net Tue Mar 23 14:32:29 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 14:32:29 +0100 (CET) Subject: [pypy-svn] r72621 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323133229.AD286282BD6@codespeak.net> Author: afa Date: Tue Mar 23 14:32:28 2010 New Revision: 72621 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Log: import cleanup Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Tue Mar 23 14:32:28 2010 @@ -1,5 +1,5 @@ -from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, Py_ssize_t +from pypy.rpython.lltypesystem import rffi +from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t @cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) def PyString_FromStringAndSize(space, char_p, length): From afa at codespeak.net Tue Mar 23 14:54:20 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 14:54:20 +0100 (CET) Subject: [pypy-svn] r72626 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323135420.F25FF282BD6@codespeak.net> Author: afa Date: Tue Mar 23 14:54:19 2010 New Revision: 72626 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/object.py Log: Replace the "dont deref" option with and automatic conversion of parameters named w_xxx Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 14:54:19 2010 @@ -45,20 +45,38 @@ class ApiFunction: - def __init__(self, argtypes, restype, callable, borrowed, dont_deref): + def __init__(self, argtypes, restype, callable, borrowed): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) self.callable = callable self.borrowed = borrowed - self.dont_deref = dont_deref -def cpython_api(argtypes, restype, borrowed=False, dont_deref=False): + # extract the signature from the (CPython-level) code object + from pypy.interpreter import pycode + argnames, varargname, kwargname = pycode.cpython_code_signature(callable.func_code) + + assert argnames[0] == 'space' + self.argnames = argnames[1:] + assert len(self.argnames) == len(self.argtypes) + + +def cpython_api(argtypes, restype, borrowed=False): def decorate(func): - api_function = ApiFunction(argtypes, restype, func, borrowed, dont_deref) + api_function = ApiFunction(argtypes, restype, func, borrowed) FUNCTIONS[func.func_name] = api_function + def unwrapper(space, *args): + newargs = [] + for i, arg in enumerate(args): + if api_function.argtypes[i] is PyObject: + if (isinstance(arg, W_Root) and + not api_function.argnames[i].startswith('w_')): + arg = make_ref(space, arg) + newargs.append(arg) + return func(space, *newargs) func.api_func = api_function - return func + unwrapper.api_func = api_function + return unwrapper return decorate def cpython_api_c(): @@ -175,8 +193,8 @@ def clear_memory(space): from pypy.module.cpyext.macros import Py_DECREF state = space.fromcache(State) - while state.py_objects_w2r: - key = state.py_objects_w2r.keys()[0] + while state.py_objects_r2w: + key = state.py_objects_r2w.keys()[0] Py_DECREF(space, key) state.reset() @@ -192,7 +210,8 @@ print >>sys.stderr, callable, for i, typ in enumerate(callable.api_func.argtypes): arg = args[i] - if typ is PyObject and not callable.api_func.dont_deref: + if (typ is PyObject and + callable.api_func.argnames[i].startswith('w_')): arg = from_ref(space, arg) boxed_args.append(arg) state = space.fromcache(State) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Tue Mar 23 14:54:19 2010 @@ -21,9 +21,7 @@ return @cpython_api([PyObject], lltype.Void) -def Py_INCREF(space, w_obj): - state = space.fromcache(State) - obj = state.py_objects_w2r.get(w_obj) +def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Tue Mar 23 14:54:19 2010 @@ -18,7 +18,7 @@ # XXX cast object according to the basesize in pto lltype.free(obj, flavor='raw') - at cpython_api([PyObject], lltype.Void, dont_deref=True) + at cpython_api([PyObject], lltype.Void) def PyObject_Del_cast(space, obj): # XXX cast object according to the basesize in pto lltype.free(obj, flavor='raw') From arigo at codespeak.net Tue Mar 23 15:27:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 15:27:31 +0100 (CET) Subject: [pypy-svn] r72628 - in pypy/trunk/pypy/jit/backend/x86: . test Message-ID: <20100323142731.46325282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 15:27:29 2010 New Revision: 72628 Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py Log: A painfully written test, and a fix for the JIT with --gcremovetypeptr. All guard_classes used to fail in that case :-( Modified: pypy/trunk/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/assembler.py (original) +++ pypy/trunk/pypy/jit/backend/x86/assembler.py Tue Mar 23 15:27:29 2010 @@ -1000,15 +1000,18 @@ # we use the following algorithm: # - read the typeid from mem(locs[0]), i.e. at offset 0 # - keep the lower 16 bits read there - # - multiply by 4 and use it as an offset in type_info_group. + # - multiply by 4 and use it as an offset in type_info_group + # - add 16 bytes, to go past the TYPE_INFO structure loc = locs[1] assert isinstance(loc, IMM32) classptr = loc.value # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header + from pypy.rpython.memory.gctypelayout import GCData + sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) - expected_typeid = (classptr - type_info_group) >> 2 + expected_typeid = (classptr - sizeof_ti - type_info_group) >> 2 mc.CMP16(mem(locs[0], 0), imm32(expected_typeid)) def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2): Modified: pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py (original) +++ pypy/trunk/pypy/jit/backend/x86/test/test_ztranslation.py Tue Mar 23 15:27:29 2010 @@ -1,10 +1,12 @@ -import py +import py, os +from pypy.tool.udir import udir from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, unroll_parameters from pypy.rlib.jit import PARAMETERS, dont_look_inside from pypy.jit.metainterp.jitprof import Profiler from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.test.support import CCompiledMixin from pypy.jit.metainterp.policy import StopAtXPolicy +from pypy.translator.translator import TranslationContext class TestTranslationX86(CCompiledMixin): CPUClass = CPU386 @@ -62,40 +64,6 @@ res = self.meta_interp(f, [40, -49]) assert res == f(40, -49) - def test_external_exception_handling_translates(self): - jitdriver = JitDriver(greens = [], reds = ['n', 'total']) - - @dont_look_inside - def f(x): - if x > 20: - return 2 - raise ValueError - @dont_look_inside - def g(x): - if x > 15: - raise ValueError - return 2 - def main(i): - jitdriver.set_param("threshold", 3) - jitdriver.set_param("trace_eagerness", 2) - total = 0 - n = i - while n > 3: - jitdriver.can_enter_jit(n=n, total=total) - jitdriver.jit_merge_point(n=n, total=total) - try: - total += f(n) - except ValueError: - total += 1 - try: - total += g(n) - except ValueError: - total -= 1 - n -= 1 - return total * 10 - res = self.meta_interp(main, [40]) - assert res == main(40) - def test_direct_assembler_call_translates(self): class Thing(object): def __init__(self, val): @@ -144,3 +112,75 @@ policy=StopAtXPolicy(change)) assert res == main(0) + +class TestTranslationRemoveTypePtrX86(CCompiledMixin): + CPUClass = CPU386 + + def _get_TranslationContext(self): + t = TranslationContext() + t.config.translation.gc = 'hybrid' + t.config.translation.gcrootfinder = 'asmgcc' + t.config.translation.list_comprehension_operations = True + t.config.translation.gcremovetypeptr = True + return t + + def test_external_exception_handling_translates(self): + jitdriver = JitDriver(greens = [], reds = ['n', 'total']) + + @dont_look_inside + def f(x): + if x > 20: + return 2 + raise ValueError + @dont_look_inside + def g(x): + if x > 15: + raise ValueError + return 2 + class Base: + def meth(self): + return 2 + class Sub(Base): + def meth(self): + return 1 + @dont_look_inside + def h(x): + if x < 2000: + return Sub() + else: + return Base() + def main(i): + jitdriver.set_param("threshold", 3) + jitdriver.set_param("trace_eagerness", 2) + total = 0 + n = i + while n > 3: + jitdriver.can_enter_jit(n=n, total=total) + jitdriver.jit_merge_point(n=n, total=total) + try: + total += f(n) + except ValueError: + total += 1 + try: + total += g(n) + except ValueError: + total -= 1 + n -= h(n).meth() # this is to force a GUARD_CLASS + return total * 10 + + # XXX custom fishing, depends on the exact env var and format + logfile = udir.join('test_ztranslation.log') + os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,) + try: + res = self.meta_interp(main, [40]) + assert res == main(40) + finally: + del os.environ['PYPYLOG'] + + guard_class = 0 + for line in open(str(logfile)): + if 'guard_class' in line: + guard_class += 1 + # if we get many more guard_classes, it means that we generate + # guards that always fail + assert 0 < guard_class <= 4 From arigo at codespeak.net Tue Mar 23 15:33:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 15:33:40 +0100 (CET) Subject: [pypy-svn] r72629 - pypy/trunk/pypy/module/cpyext Message-ID: <20100323143340.88A99282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 15:33:39 2010 New Revision: 72629 Modified: pypy/trunk/pypy/module/cpyext/typeobject.py Log: Untabiffy (ignore this change when merging). Modified: pypy/trunk/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/trunk/pypy/module/cpyext/typeobject.py (original) +++ pypy/trunk/pypy/module/cpyext/typeobject.py Tue Mar 23 15:33:39 2010 @@ -70,7 +70,7 @@ setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real)) PyGetSetDef = cpython_struct("PyGetSetDef", ( - ("name", rffi.CCHARP), + ("name", rffi.CCHARP), ("get", getter), ("set", setter), ("doc", rffi.CCHARP), From afa at codespeak.net Tue Mar 23 17:09:21 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 17:09:21 +0100 (CET) Subject: [pypy-svn] r72636 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323160921.524EC282BD6@codespeak.net> Author: afa Date: Tue Mar 23 17:09:19 2010 New Revision: 72636 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Py_INCREF and Py_DECREF don't need to access the pypy object in the standard case Remove support for "borrowed" references, needs more thinking Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Tue Mar 23 17:09:19 2010 @@ -2,6 +2,10 @@ - Implement C API. - Complete the PyTypeObject initialization code. - Free pto.c_tp_name correctly + - properly support "borrowed" references: the PyObject must be stored + somewhere + - lltype.free in PyObject_Del() sometimes raise an exception (but all + tests pass) PyStringObject support ====================== Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 17:09:19 2010 @@ -65,15 +65,28 @@ def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed) FUNCTIONS[func.func_name] = api_function + def unwrapper(space, *args): + "NOT_RPYTHON: XXX unsure" newargs = [] + to_decref = [] for i, arg in enumerate(args): if api_function.argtypes[i] is PyObject: if (isinstance(arg, W_Root) and not api_function.argnames[i].startswith('w_')): arg = make_ref(space, arg) + to_decref.append(arg) + elif (not isinstance(arg, W_Root) and + api_function.argnames[i].startswith('w_')): + arg = from_ref(space, arg) newargs.append(arg) - return func(space, *newargs) + try: + return func(space, *newargs) + finally: + from pypy.module.cpyext.macros import Py_DECREF + for arg in to_decref: + Py_DECREF(space, arg) + func.api_func = api_function unwrapper.api_func = api_function return unwrapper @@ -175,8 +188,9 @@ py_obj = rffi.cast(PyObject, py_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj - elif not borrowed: + else: py_obj.c_obj_refcnt += 1 + # XXX borrowed references? return py_obj def from_ref(space, ref): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Tue Mar 23 17:09:19 2010 @@ -6,35 +6,29 @@ # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) -def Py_DECREF(space, w_obj): - print "DECREF", w_obj - state = space.fromcache(State) - obj = state.py_objects_w2r[w_obj] +def Py_DECREF(space, obj): obj.c_obj_refcnt -= 1 if obj.c_obj_refcnt == 0: + state = space.fromcache(State) ptr = ctypes.addressof(obj._obj._storage) - _Py_Dealloc(space, w_obj) + w_obj = state.py_objects_r2w.pop(ptr) + _Py_Dealloc(space, obj) del state.py_objects_w2r[w_obj] - del state.py_objects_r2w[ptr] else: assert obj.c_obj_refcnt > 0 - return @cpython_api([PyObject], lltype.Void) def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 -def _Py_Dealloc(space, w_obj): +def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr from pypy.module.cpyext.methodobject import generic_cpy_call state = space.fromcache(State) - w_type = space.type(w_obj) - pto = make_ref(space, w_type) + pto = obj.c_obj_type pto = rffi.cast(PyTypeObjectPtr, pto) - try: - print "Calling ", pto.c_tp_dealloc, "of", w_obj, "'s type which is", w_type - generic_cpy_call(space, pto.c_tp_dealloc, w_obj, decref_args=False) - finally: - Py_DECREF(space, w_type) # make_ref bumps refcount + print "Calling ", pto.c_tp_dealloc, "of", obj, \ + "'s type which is", rffi.charp2str(pto.c_tp_name) + generic_cpy_call(space, pto.c_tp_dealloc, obj, decref_args=False) From xoraxax at codespeak.net Tue Mar 23 18:09:32 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 18:09:32 +0100 (CET) Subject: [pypy-svn] r72642 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323170932.8ED33282BD6@codespeak.net> Author: xoraxax Date: Tue Mar 23 18:09:30 2010 New Revision: 72642 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: Move generic_cpy_call and from_ref_ex from methodsobject to api. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 23 18:09:30 2010 @@ -393,3 +393,42 @@ initfunc.call(lltype.Void) state.check_and_raise_exception() +def generic_cpy_call(space, func, *args, **kwargs): + from pypy.module.cpyext.macros import Py_DECREF + decref_args = kwargs.pop("decref_args", True) + assert not kwargs + boxed_args = [] + for arg in args: # XXX ur needed + if isinstance(arg, W_Root) or arg is None: + boxed_args.append(make_ref(space, arg)) + else: + boxed_args.append(arg) + result = func(*boxed_args) + try: + FT = lltype.typeOf(func).TO + if FT.RESULT is not lltype.Void: + ret = from_ref_ex(space, result) + Py_DECREF(space, ret) + return ret + finally: + if decref_args: + for arg in args: # XXX ur needed + if arg is not None and isinstance(arg, W_Root): + Py_DECREF(space, arg) + +def from_ref_ex(space, result): + try: + ret = from_ref(space, result) + except NullPointerException: + state = space.fromcache(State) + state.check_and_raise_exception() + assert False, "NULL returned but no exception set" + except InvalidPointerException: + if not we_are_translated(): + import sys + print >>sys.stderr, "Calling a C function return an invalid PyObject" \ + " pointer." + raise + return ret + + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Tue Mar 23 18:09:30 2010 @@ -6,50 +6,12 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.function import BuiltinFunction, Method from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import PyObject, from_ref, NullPointerException, \ - InvalidPointerException, make_ref +from pypy.module.cpyext.api import PyObject, from_ref, \ + make_ref, generic_cpy_call, from_ref_ex from pypy.module.cpyext.state import State -from pypy.module.cpyext.macros import Py_DECREF from pypy.rlib.objectmodel import we_are_translated -def from_ref_ex(space, result): - try: - ret = from_ref(space, result) - except NullPointerException: - state = space.fromcache(State) - state.check_and_raise_exception() - assert False, "NULL returned but no exception set" - except InvalidPointerException: - if not we_are_translated(): - import sys - print >>sys.stderr, "Calling a C function return an invalid PyObject" \ - " pointer." - raise - return ret - -def generic_cpy_call(space, func, *args, **kwargs): - decref_args = kwargs.pop("decref_args", True) - assert not kwargs - boxed_args = [] - for arg in args: # XXX ur needed - if isinstance(arg, W_Root) or arg is None: - boxed_args.append(make_ref(space, arg)) - else: - boxed_args.append(arg) - result = func(*boxed_args) - try: - FT = lltype.typeOf(func).TO - if FT.RESULT is not lltype.Void: - ret = from_ref_ex(space, result) - Py_DECREF(space, ret) - return ret - finally: - if decref_args: - for arg in args: # XXX ur needed - if arg is not None and isinstance(arg, W_Root): - Py_DECREF(space, arg) - # XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): def __init__(self, space, ml, w_self): From xoraxax at codespeak.net Tue Mar 23 18:10:25 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 23 Mar 2010 18:10:25 +0100 (CET) Subject: [pypy-svn] r72644 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100323171025.3C724282BD6@codespeak.net> Author: xoraxax Date: Tue Mar 23 18:10:23 2010 New Revision: 72644 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Implement dealloc slot of object correctly (needs to call into the free slot of the type object). Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Tue Mar 23 18:10:23 2010 @@ -1,6 +1,8 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ + generic_cpy_call from pypy.module.cpyext.state import State +from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject @@ -19,7 +21,8 @@ lltype.free(obj, flavor='raw') @cpython_api([PyObject], lltype.Void) -def PyObject_Del_cast(space, obj): - # XXX cast object according to the basesize in pto - lltype.free(obj, flavor='raw') +def PyObject_dealloc(space, obj): + pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + obj_voidp = rffi.cast(rffi.VOIDP_real, obj) + generic_cpy_call(space, pto.c_tp_free, obj_voidp) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Tue Mar 23 18:10:23 2010 @@ -220,9 +220,9 @@ def allocate_type_obj(space, w_type): - from pypy.module.cpyext.object import PyObject_Del_cast, PyObject_Del + from pypy.module.cpyext.object import PyObject_dealloc, PyObject_Del pto = lltype.malloc(PyTypeObject, None, flavor="raw") - callable = PyObject_Del_cast + callable = PyObject_dealloc pto.c_tp_dealloc = llhelper(callable.api_func.functype, make_wrapper(space, callable)) callable = PyObject_Del From getxsick at codespeak.net Tue Mar 23 20:47:04 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 20:47:04 +0100 (CET) Subject: [pypy-svn] r72650 - pypy/trunk/pypy/module/_socket/test Message-ID: <20100323194704.1EF69282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 20:47:02 2010 New Revision: 72650 Modified: pypy/trunk/pypy/module/_socket/test/test_sock_app.py Log: Skip tests for GAIErrors. That helps with failing when there is no connection. In these tests we don't investigate getaddrinfo() / getnameinfo() (there are appropriate unit tests for these functions). Life is good. However XXX section is still alive.. 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 Mar 23 20:47:02 2010 @@ -314,9 +314,12 @@ import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) # XXX temporarily we use codespeak to test, will have more robust tests in - # the absence of a network connection later when mroe parts of the socket - # API are implemented. - s.connect(("codespeak.net", 80)) + # the absence of a network connection later when more parts of the socket + # API are implemented. currently skip the test if there is no connection. + try: + s.connect(("codespeak.net", 80)) + except _socket.gaierror, ex: + skip("GAIError - probably no connection: %s" % str(ex.args)) name = s.getpeername() # Will raise socket.error if not connected assert name[1] == 80 s.close() @@ -399,9 +402,12 @@ import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) # XXX temporarily we use codespeak to test, will have more robust tests in - # the absence of a network connection later when mroe parts of the socket - # API are implemented. - s.connect(("codespeak.net", 80)) + # the absence of a network connection later when more parts of the socket + # API are implemented. currently skip the test if there is no connection. + try: + s.connect(("codespeak.net", 80)) + except _socket.gaierror, ex: + skip("GAIError - probably no connection: %s" % str(ex.args)) s.send(buffer('')) s.sendall(buffer('')) s.send(u'') From afa at codespeak.net Tue Mar 23 20:49:40 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 23 Mar 2010 20:49:40 +0100 (CET) Subject: [pypy-svn] r72651 - pypy/trunk/pypy/translator/c/winproj Message-ID: <20100323194940.1365A282BD6@codespeak.net> Author: afa Date: Tue Mar 23 20:49:39 2010 New Revision: 72651 Removed: pypy/trunk/pypy/translator/c/winproj/ Log: Remove old, outdated, and unusable static project files From arigo at codespeak.net Tue Mar 23 20:50:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 20:50:44 +0100 (CET) Subject: [pypy-svn] r72652 - pypy/trunk/pypy/lib Message-ID: <20100323195044.09F30282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 20:50:43 2010 New Revision: 72652 Removed: pypy/trunk/pypy/lib/functional.py Log: Remove old pre-version of functools.py. From getxsick at codespeak.net Tue Mar 23 20:56:41 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 20:56:41 +0100 (CET) Subject: [pypy-svn] r72653 - pypy/build/ubuntu/1.2.0 Message-ID: <20100323195641.29A88282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 20:56:39 2010 New Revision: 72653 Added: pypy/build/ubuntu/1.2.0/ Log: Create Ubuntu package's scripts for 1.2.0 release. It can be still helpful for a while. From getxsick at codespeak.net Tue Mar 23 20:57:10 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 20:57:10 +0100 (CET) Subject: [pypy-svn] r72654 - in pypy/build/ubuntu: 1.2.0/debian debian Message-ID: <20100323195710.F0E0D282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 20:57:09 2010 New Revision: 72654 Added: pypy/build/ubuntu/1.2.0/debian/ - copied from r72653, pypy/build/ubuntu/debian/ Removed: pypy/build/ubuntu/debian/ Log: Move scripts to 1.2.0/ From getxsick at codespeak.net Tue Mar 23 20:57:57 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 20:57:57 +0100 (CET) Subject: [pypy-svn] r72655 - pypy/build/ubuntu/trunk Message-ID: <20100323195757.D5836282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 20:57:56 2010 New Revision: 72655 Added: pypy/build/ubuntu/trunk/ Log: Create scripts directory for the trunk From getxsick at codespeak.net Tue Mar 23 20:59:49 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 20:59:49 +0100 (CET) Subject: [pypy-svn] r72656 - pypy/build/ubuntu/trunk/debian Message-ID: <20100323195949.19707282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 20:59:47 2010 New Revision: 72656 Added: pypy/build/ubuntu/trunk/debian/ - copied from r72655, pypy/build/ubuntu/1.2.0/debian/ Log: Copy 1.2.0 scripts to trunk From getxsick at codespeak.net Tue Mar 23 21:03:01 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 21:03:01 +0100 (CET) Subject: [pypy-svn] r72657 - pypy/build/ubuntu/trunk/debian Message-ID: <20100323200301.31440282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 21:02:21 2010 New Revision: 72657 Modified: pypy/build/ubuntu/trunk/debian/rules Log: Update rules Modified: pypy/build/ubuntu/trunk/debian/rules ============================================================================== --- pypy/build/ubuntu/trunk/debian/rules (original) +++ pypy/build/ubuntu/trunk/debian/rules Tue Mar 23 21:02:21 2010 @@ -55,7 +55,6 @@ rm debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/module/unicodedata/LICENSE rm debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/py rm debian/pypy-lib/usr/share/pypy-$(VERSION)/pypy/lib/app_test/ctypes_tests/_ctypes_test.o - rm -r debian/pypy-dev/usr/share/pypy-$(VERSION)/pypy/translator/c/winproj/ chmod a-x debian/pypy-lib/usr/share/pypy-$(VERSION)/lib-python/2.5.2/idlelib/idle.bat install-arch: From getxsick at codespeak.net Tue Mar 23 21:08:56 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 23 Mar 2010 21:08:56 +0100 (CET) Subject: [pypy-svn] r72658 - pypy/build/ubuntu/1.2.0/debian Message-ID: <20100323200856.EAE06282BD6@codespeak.net> Author: getxsick Date: Tue Mar 23 21:08:19 2010 New Revision: 72658 Modified: pypy/build/ubuntu/1.2.0/debian/rules Log: update get-orig-source to 1.2.0 Modified: pypy/build/ubuntu/1.2.0/debian/rules ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/rules (original) +++ pypy/build/ubuntu/1.2.0/debian/rules Tue Mar 23 21:08:19 2010 @@ -13,11 +13,11 @@ get-orig-source: set -e ; \ - svn co http://codespeak.net/svn/pypy/trunk pypy-svn ; \ - REVISION=`svnversion pypy-svn/` ; \ - find pypy-svn/ -depth -type d -name ".svn" | xargs rm -rf ; \ - tar cfz pypy_$(VERSION).0-svn$$REVISION.orig.tar.gz pypy-svn/ ; \ - rm -rf pypy-svn/ + svn co http://codespeak.net/svn/pypy/release/1.2.0 pypy-1.2.0 ; \ + REVISION=`svnversion pypy-1.2.0/` ; \ + find pypy-1.2.0/ -depth -type d -name ".svn" | xargs rm -rf ; \ + tar cfz pypy_$(VERSION).0-svn$$REVISION.orig.tar.gz pypy-1.2.0/ ; \ + rm -rf pypy-1.2.0/ Makefile: debian/Makefile.in python debian/configure.py --build=$(DEB_BUILD_ARCH) --host=$(DEB_HOST_ARCH) --prefix=debian/tmp/usr debian/Makefile.in From jandem at codespeak.net Tue Mar 23 21:18:06 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Tue, 23 Mar 2010 21:18:06 +0100 (CET) Subject: [pypy-svn] r72659 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100323201806.324A9282BD6@codespeak.net> Author: jandem Date: Tue Mar 23 21:17:56 2010 New Revision: 72659 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Add PyTuple_GetItem and a failing test Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h Tue Mar 23 21:17:56 2010 @@ -9,6 +9,7 @@ PyObject * PyTuple_New(Py_ssize_t size); PyObject * PyTuple_Pack(Py_ssize_t, ...); +PyObject * PyTuple_GetItem(PyObject *, Py_ssize_t); int PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); #ifdef __cplusplus Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 23 21:17:56 2010 @@ -224,6 +224,25 @@ skip("Hmm, how to check for the exception?") raises(api.InvalidPointerException, module.return_invalid_pointer) + def test_argument(self): + import sys + init = """ + if (Py_IsInitialized()) + Py_InitModule("foo", methods); + """ + body = """ + PyObject* foo_test(PyObject* self, PyObject *args) + { + return PyTuple_GetItem(args, 0); + } + static PyMethodDef methods[] = { + { "test", foo_test, METH_VARARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert module.test(True, True) == True + def test_exception(self): import sys init = """ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Tue Mar 23 21:17:56 2010 @@ -14,3 +14,9 @@ w_t.wrappeditems[pos] = w_obj Py_DECREF(space, w_obj) # SetItem steals a reference! return 0 + + at cpython_api([PyObject, Py_ssize_t], PyObject) +def PyTuple_GetItem(space, w_t, pos): + assert isinstance(w_t, W_TupleObject) + w_obj = w_t.wrappeditems[pos] + return w_obj From arigo at codespeak.net Tue Mar 23 21:39:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 21:39:24 +0100 (CET) Subject: [pypy-svn] r72660 - pypy/branch/fix-64 Message-ID: <20100323203924.6B4A8282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 21:39:22 2010 New Revision: 72660 Modified: pypy/branch/fix-64/ (props changed) Log: Trying, a bit randomly, to remove the bzr: properties in order to improve "svn ls http://xxx". From lucian at codespeak.net Tue Mar 23 21:52:55 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 23 Mar 2010 21:52:55 +0100 (CET) Subject: [pypy-svn] r72662 - pypy/trunk/pypy/translator/platform Message-ID: <20100323205255.84BC0282BD6@codespeak.net> Author: lucian Date: Tue Mar 23 21:52:54 2010 New Revision: 72662 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Switch from .bundle to .dylib on OS X. This fixes many failing cpyext tests and so far lltypesystem tests pass. I hope the buildbot won't discover any new failing tests. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Tue Mar 23 21:52:54 2010 @@ -18,14 +18,14 @@ self.cc = cc def _args_for_shared(self, args): - return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + return (self.shared_only + ['-dynamiclib', '-undefined', 'dynamic_lookup'] + args) def include_dirs_for_libffi(self): return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return [] + return ['/usr/lib/'] def check___thread(self): # currently __thread is not supported by Darwin gccs From lucian at codespeak.net Tue Mar 23 22:03:23 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 23 Mar 2010 22:03:23 +0100 (CET) Subject: [pypy-svn] r72663 - pypy/trunk/pypy/translator/platform Message-ID: <20100323210323.75D59282BD6@codespeak.net> Author: lucian Date: Tue Mar 23 22:03:22 2010 New Revision: 72663 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Revert change to .dylibs because it's dangerous to play with fire on trunk. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Tue Mar 23 22:03:22 2010 @@ -18,14 +18,14 @@ self.cc = cc def _args_for_shared(self, args): - return (self.shared_only + ['-dynamiclib', '-undefined', 'dynamic_lookup'] + return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + args) def include_dirs_for_libffi(self): return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return ['/usr/lib/'] + return [] def check___thread(self): # currently __thread is not supported by Darwin gccs From arigo at codespeak.net Tue Mar 23 22:04:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:04:00 +0100 (CET) Subject: [pypy-svn] r72664 - pypy/branch/guard-value-counting Message-ID: <20100323210400.7CEA2282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:03:59 2010 New Revision: 72664 Removed: pypy/branch/guard-value-counting/ Log: That branch dies for now. From arigo at codespeak.net Tue Mar 23 22:07:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:07:19 +0100 (CET) Subject: [pypy-svn] r72665 - pypy/branch/gcmaptable-c Message-ID: <20100323210719.0A927282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:07:17 2010 New Revision: 72665 Removed: pypy/branch/gcmaptable-c/ Log: Remove branch. The corresponding work was done directly on trunk. From arigo at codespeak.net Tue Mar 23 22:08:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:08:46 +0100 (CET) Subject: [pypy-svn] r72666 - pypy/branch/asmgcc-exception Message-ID: <20100323210846.60EE1282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:08:44 2010 New Revision: 72666 Removed: pypy/branch/asmgcc-exception/ Log: Remove branch that went nowhere. From lucian at codespeak.net Tue Mar 23 22:13:24 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 23 Mar 2010 22:13:24 +0100 (CET) Subject: [pypy-svn] r72667 - pypy/trunk/pypy/translator/platform Message-ID: <20100323211324.DC1D636C225@codespeak.net> Author: lucian Date: Tue Mar 23 22:13:23 2010 New Revision: 72667 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Add missing library path for the darwin translator backend. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Tue Mar 23 22:13:23 2010 @@ -25,7 +25,7 @@ return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return [] + return ['/usr/lib'] def check___thread(self): # currently __thread is not supported by Darwin gccs From lucian at codespeak.net Tue Mar 23 22:14:50 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 23 Mar 2010 22:14:50 +0100 (CET) Subject: [pypy-svn] r72668 - pypy/branch/cpython-extension/pypy/translator/platform Message-ID: <20100323211450.72962282BD6@codespeak.net> Author: lucian Date: Tue Mar 23 22:14:48 2010 New Revision: 72668 Modified: pypy/branch/cpython-extension/pypy/translator/platform/darwin.py Log: Switch from .bundle to .dylib for shared objects on darwin. This branch can catch fire, but trunk will be safe. Modified: pypy/branch/cpython-extension/pypy/translator/platform/darwin.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/darwin.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/darwin.py Tue Mar 23 22:14:48 2010 @@ -18,14 +18,14 @@ self.cc = cc def _args_for_shared(self, args): - return (self.shared_only + ['-bundle', '-undefined', 'dynamic_lookup'] + return (self.shared_only + ['-dynamiclib', '-undefined', 'dynamic_lookup'] + args) def include_dirs_for_libffi(self): return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return [] + return ['/usr/lib'] def check___thread(self): # currently __thread is not supported by Darwin gccs From arigo at codespeak.net Tue Mar 23 22:21:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:21:00 +0100 (CET) Subject: [pypy-svn] r72669 - pypy/branch/dist-future-fixing Message-ID: <20100323212100.4ABF4282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:20:58 2010 New Revision: 72669 Removed: pypy/branch/dist-future-fixing/ Log: Remove old branch, which was partially merged by r49081. From arigo at codespeak.net Tue Mar 23 22:29:05 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:29:05 +0100 (CET) Subject: [pypy-svn] r72670 - pypy/branch/faster-raise Message-ID: <20100323212905.26101282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:29:03 2010 New Revision: 72670 Removed: pypy/branch/faster-raise/ Log: Remove (probably) merged branch. From arigo at codespeak.net Tue Mar 23 22:30:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:30:35 +0100 (CET) Subject: [pypy-svn] r72671 - pypy/branch/force-arch-darwin Message-ID: <20100323213035.B7A2C282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:30:33 2010 New Revision: 72671 Removed: pypy/branch/force-arch-darwin/ Log: Remove partially merged branch (r70305). From arigo at codespeak.net Tue Mar 23 22:31:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:31:50 +0100 (CET) Subject: [pypy-svn] r72672 - pypy/branch/gc-dump-malloc Message-ID: <20100323213150.D238F282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:31:49 2010 New Revision: 72672 Removed: pypy/branch/gc-dump-malloc/ Log: Remove branch which is getting out-of-date. From arigo at codespeak.net Tue Mar 23 22:33:14 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:33:14 +0100 (CET) Subject: [pypy-svn] r72673 - pypy/branch/gc-jit-hack Message-ID: <20100323213314.0152D282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:33:13 2010 New Revision: 72673 Removed: pypy/branch/gc-jit-hack/ Log: Remove a branch that did not give the expected results. From arigo at codespeak.net Tue Mar 23 22:34:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:34:09 +0100 (CET) Subject: [pypy-svn] r72674 - pypy/branch/gc-prebuilt-dying Message-ID: <20100323213409.22C65282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:34:07 2010 New Revision: 72674 Removed: pypy/branch/gc-prebuilt-dying/ Log: Kill this branch until we find a new idea to restart it. From arigo at codespeak.net Tue Mar 23 22:37:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Mar 2010 22:37:55 +0100 (CET) Subject: [pypy-svn] r72675 - pypy/branch/pyjitpl5-simplify-pygirl Message-ID: <20100323213755.EE453282BD6@codespeak.net> Author: arigo Date: Tue Mar 23 22:37:54 2010 New Revision: 72675 Removed: pypy/branch/pyjitpl5-simplify-pygirl/ Log: Kill old branch. From benjamin at codespeak.net Tue Mar 23 22:48:21 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 23 Mar 2010 22:48:21 +0100 (CET) Subject: [pypy-svn] r72676 - pypy/branch/classdeco Message-ID: <20100323214821.76C9D282BD6@codespeak.net> Author: benjamin Date: Tue Mar 23 22:48:19 2010 New Revision: 72676 Removed: pypy/branch/classdeco/ Log: not going to anything with this branch From lucian at codespeak.net Wed Mar 24 01:23:02 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Wed, 24 Mar 2010 01:23:02 +0100 (CET) Subject: [pypy-svn] r72677 - pypy/trunk/pypy/translator/platform Message-ID: <20100324002302.88608282BD6@codespeak.net> Author: lucian Date: Wed Mar 24 01:23:00 2010 New Revision: 72677 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Change extension of libraries generated for OS X to .bundle for consiscency and to avoid confusion. Translator and lltypesystem tests pass. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Wed Mar 24 01:23:00 2010 @@ -10,7 +10,7 @@ standalone_only = ['-mdynamic-no-pic'] shared_only = [] - so_ext = 'so' + so_ext = 'bundle' def __init__(self, cc=None): if cc is None: From lucian at codespeak.net Wed Mar 24 01:47:09 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Wed, 24 Mar 2010 01:47:09 +0100 (CET) Subject: [pypy-svn] r72678 - pypy/trunk/pypy/translator/platform Message-ID: <20100324004709.6FBB3282BD6@codespeak.net> Author: lucian Date: Wed Mar 24 01:47:07 2010 New Revision: 72678 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Revert last change. CPython does not follow platform file naming conventions, its extensions on OS X end in .so instead of .bundle, even though they are Mach-O bundles. CPython should change, but in the meantime PyPy should follow CPython's behaviour. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Wed Mar 24 01:47:07 2010 @@ -25,7 +25,7 @@ return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return ['/usr/lib'] + return [] def check___thread(self): # currently __thread is not supported by Darwin gccs From arigo at codespeak.net Wed Mar 24 09:25:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 09:25:17 +0100 (CET) Subject: [pypy-svn] r72691 - in pypy/build/testrunner: . test Message-ID: <20100324082517.DBBBE282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 09:25:15 2010 New Revision: 72691 Modified: pypy/build/testrunner/runner.py pypy/build/testrunner/test/test_runner.py Log: Improve the busywaiting logic and move it into its own tested function. Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Wed Mar 24 09:25:15 2010 @@ -41,6 +41,19 @@ RUNFAILED = -1000 TIMEDOUT = -999 +def busywait(p, timeout): + t0 = time.time() + delay = 0.5 + while True: + time.sleep(delay) + returncode = p.poll() + if returncode is not None: + return returncode + tnow = time.time() + if (tnow-t0) >= timeout: + return None + delay = min(delay * 1.15, 7.2) + def run(args, cwd, out, timeout=None): f = out.open('w') try: @@ -55,21 +68,14 @@ if timeout is None: return p.wait() else: - timedout = None - t0 = time.time() - while True: - returncode = p.poll() - if returncode is not None: - return timedout or returncode - tnow = time.time() - if (tnow-t0) > timeout: - if timedout: - _kill(p.pid, SIGKILL) - return TIMEDOUT - else: - timedout = TIMEDOUT - _kill(p.pid, SIGTERM) - time.sleep(3) + returncode = busywait(p, timeout) + if returncode is not None: + return returncode + # timeout! + _kill(p.pid, SIGTERM) + if busywait(p, 10) is None: + _kill(p.pid, SIGKILL) + return TIMEDOUT finally: f.close() Modified: pypy/build/testrunner/test/test_runner.py ============================================================================== --- pypy/build/testrunner/test/test_runner.py (original) +++ pypy/build/testrunner/test/test_runner.py Wed Mar 24 09:25:15 2010 @@ -5,6 +5,44 @@ pytest_script = py.path.local(pypy.__file__).dirpath('test_all.py') + +def test_busywait(): + class FakeProcess: + def poll(self): + if timers[0] >= timers[1]: + return 42 + return None + class FakeTime: + def sleep(self, delay): + timers[0] += delay + def time(self): + timers[2] += 1 + return 12345678.9 + timers[0] + p = FakeProcess() + prevtime = runner.time + try: + runner.time = FakeTime() + # + timers = [0.0, 0.0, 0] + returncode = runner.busywait(p, 10) + assert returncode == 42 and 0.0 <= timers[0] <= 1.0 + # + timers = [0.0, 3.0, 0] + returncode = runner.busywait(p, 10) + assert returncode == 42 and 3.0 <= timers[0] <= 5.0 and timers[2] <= 10 + # + timers = [0.0, 500.0, 0] + returncode = runner.busywait(p, 1000) + assert returncode == 42 and 500.0<=timers[0]<=510.0 and timers[2]<=100 + # + timers = [0.0, 500.0, 0] + returncode = runner.busywait(p, 100) # get a timeout + assert returncode == None and 100.0 <= timers[0] <= 110.0 + # + finally: + runner.time = prevtime + + class TestRunHelper(object): def setup_method(self, meth): From arigo at codespeak.net Wed Mar 24 09:49:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 09:49:35 +0100 (CET) Subject: [pypy-svn] r72692 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100324084935.48565282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 09:49:33 2010 New Revision: 72692 Modified: pypy/trunk/pypy/objspace/std/floatobject.py pypy/trunk/pypy/objspace/std/test/test_floatobject.py Log: Be more precise in handling ValueErrors from math.pow() in 'float**float'. This improves error messages in one case, and allows '-1.0**largenum' to succeed (and return 1.0) even though math.pow() fails on the same arguments. That's a big strange, but the way it is in CPython 2.6. Modified: pypy/trunk/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/floatobject.py Wed Mar 24 09:49:33 2010 @@ -318,7 +318,20 @@ raise FailedToImplementArgs(space.w_OverflowError, space.wrap("float power")) except ValueError: - if x == 0.0 and y < 0.0: + # special case: "(-1.0) ** bignum" should not raise ValueError, + # unlike "math.pow(-1.0, bignum)". See http://mail.python.org/ + # - pipermail/python-bugs-list/2003-March/016795.html + if x < 0.0: + if math.floor(y) != y: + raise OperationError(space.w_ValueError, + space.wrap("negative number cannot be " + "raised to a fractional power")) + if x == -1.0: + if math.floor(y * 0.5) * 2.0 == y: + return space.wrap(1.0) + else: + return space.wrap( -1.0) + elif x == 0.0 and y < 0.0: raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 cannot be raised to a negative power")) raise OperationError(space.w_ValueError, Modified: pypy/trunk/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_floatobject.py Wed Mar 24 09:49:33 2010 @@ -146,8 +146,7 @@ raises(ValueError, pw, -1.0, 0.5) assert pw(-1.0, 2.0) == 1.0 assert pw(-1.0, 3.0) == -1.0 - #assert pw(-1.0, 1e200) == 1.0 -- either 1.0, or ValueError, are - # -- acceptable answers IMHO + assert pw(-1.0, 1e200) == 1.0 def test_pow_neg_base(self): def pw(x, y): From arigo at codespeak.net Wed Mar 24 10:23:59 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 10:23:59 +0100 (CET) Subject: [pypy-svn] r72693 - pypy/trunk/pypy/module/cpyext Message-ID: <20100324092359.C5788282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 10:23:58 2010 New Revision: 72693 Removed: pypy/trunk/pypy/module/cpyext/ Log: Delete this from trunk. It's causing some obscure test failures, notably api.py contains some CPython 2.6-only syntax. From arigo at codespeak.net Wed Mar 24 10:33:24 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 10:33:24 +0100 (CET) Subject: [pypy-svn] r72694 - pypy/branch/effect-analysis Message-ID: <20100324093324.3F60E282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 10:33:22 2010 New Revision: 72694 Removed: pypy/branch/effect-analysis/ Log: Remove this branch, as per e-mail to pypy-dev. From arigo at codespeak.net Wed Mar 24 11:09:35 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 11:09:35 +0100 (CET) Subject: [pypy-svn] r72695 - in pypy/build/testrunner: . test Message-ID: <20100324100935.25564282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 11:09:33 2010 New Revision: 72695 Modified: pypy/build/testrunner/runner.py pypy/build/testrunner/test/test_runner.py Log: Add a case: when we see an exit code of 1, check the log file to see if there is any reported failure in it. If not, report the whole run as failed. Modified: pypy/build/testrunner/runner.py ============================================================================== --- pypy/build/testrunner/runner.py (original) +++ pypy/build/testrunner/runner.py Wed Mar 24 11:09:33 2010 @@ -114,11 +114,24 @@ return exitcode -def interpret_exitcode(exitcode, test): +def should_report_failure(logdata): + # When we have an exitcode of 1, it might be because of failures + # that occurred "regularly", or because of another crash of py.test. + # We decide heuristically based on logdata: if it looks like it + # contains "F", "E" or "P" then it's a regular failure, otherwise + # we have to report it. + for line in logdata.splitlines(): + if (line.startswith('F ') or + line.startswith('E ') or + line.startswith('P ')): + return False + return True + +def interpret_exitcode(exitcode, test, logdata=""): extralog = "" if exitcode: failure = True - if exitcode != 1: + if exitcode != 1 or should_report_failure(logdata): if exitcode > 0: msg = "Exit code %d." % exitcode elif exitcode == TIMEDOUT: @@ -177,7 +190,7 @@ else: logdata = "" - failure, extralog = interpret_exitcode(exitcode, test) + failure, extralog = interpret_exitcode(exitcode, test, logdata) if extralog: logdata += extralog Modified: pypy/build/testrunner/test/test_runner.py ============================================================================== --- pypy/build/testrunner/test/test_runner.py (original) +++ pypy/build/testrunner/test/test_runner.py Wed Mar 24 11:09:33 2010 @@ -42,6 +42,16 @@ finally: runner.time = prevtime +def test_should_report_failure(): + should_report_failure = runner.should_report_failure + assert should_report_failure("") + assert should_report_failure(". Abc\n. Def\n") + assert should_report_failure("s Ghi\n") + assert not should_report_failure(". Abc\nF Def\n") + assert not should_report_failure(". Abc\nE Def\n") + assert not should_report_failure(". Abc\nP Def\n") + assert not should_report_failure("F Def\n. Ghi\n. Jkl\n") + class TestRunHelper(object): @@ -153,10 +163,15 @@ assert not failure assert extralog == "" - failure, extralog = runner.interpret_exitcode(1, "test_foo") + failure, extralog = runner.interpret_exitcode(1, "test_foo", "") assert failure - assert extralog == "" + assert extralog == """! test_foo + Exit code 1. +""" + failure, extralog = runner.interpret_exitcode(1, "test_foo", "F Foo\n") + assert failure + assert extralog == "" failure, extralog = runner.interpret_exitcode(2, "test_foo") assert failure From arigo at codespeak.net Wed Mar 24 11:15:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 11:15:29 +0100 (CET) Subject: [pypy-svn] r72696 - pypy/branch/fix-64/pypy/rpython/memory/test Message-ID: <20100324101529.94B0D282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 11:15:28 2010 New Revision: 72696 Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Log: Fix. Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Wed Mar 24 11:15:28 2010 @@ -4,7 +4,7 @@ from pypy.translator.c import gc from pypy.annotation import model as annmodel from pypy.annotation import policy as annpolicy -from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi, llgroup from pypy.rpython.memory.gctransform import framework from pypy.rpython.lltypesystem.lloperation import llop, void from pypy.rpython.memory.gc.marksweep import X_CLONE, X_POOL, X_POOL_PTR @@ -753,7 +753,7 @@ graph = graphof(translator, g) for op in graph.startblock.operations: if op.opname == 'do_malloc_fixedsize_clear': - op.args = [Constant(type_id, rffi.USHORT), + op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), Constant(True, lltype.Bool), # can_collect Constant(False, lltype.Bool), # has_finalizer @@ -790,7 +790,7 @@ graph = graphof(translator, g) for op in graph.startblock.operations: if op.opname == 'do_malloc_fixedsize_clear': - op.args = [Constant(type_id, rffi.USHORT), + op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), Constant(True, lltype.Bool), # can_collect Constant(False, lltype.Bool), # has_finalizer From lucian at codespeak.net Wed Mar 24 11:24:54 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Wed, 24 Mar 2010 11:24:54 +0100 (CET) Subject: [pypy-svn] r72697 - pypy/trunk/pypy/translator/platform Message-ID: <20100324102454.8285D282BD6@codespeak.net> Author: lucian Date: Wed Mar 24 11:24:53 2010 New Revision: 72697 Modified: pypy/trunk/pypy/translator/platform/darwin.py Log: Revert the change to .bundle and revert the unintended revert of the addition of a library path. Modified: pypy/trunk/pypy/translator/platform/darwin.py ============================================================================== --- pypy/trunk/pypy/translator/platform/darwin.py (original) +++ pypy/trunk/pypy/translator/platform/darwin.py Wed Mar 24 11:24:53 2010 @@ -10,7 +10,7 @@ standalone_only = ['-mdynamic-no-pic'] shared_only = [] - so_ext = 'bundle' + so_ext = 'so' def __init__(self, cc=None): if cc is None: @@ -25,7 +25,7 @@ return ['/usr/include/ffi'] def library_dirs_for_libffi(self): - return [] + return ['/usr/lib'] def check___thread(self): # currently __thread is not supported by Darwin gccs From arigo at codespeak.net Wed Mar 24 11:29:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 11:29:57 +0100 (CET) Subject: [pypy-svn] r72698 - pypy/branch/fix-64/pypy/rpython/memory/test Message-ID: <20100324102957.7A38A282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 11:29:55 2010 New Revision: 72698 Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py Log: Fix: GcArray(Float) is too large on 64 bits for some of these tests. Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py Wed Mar 24 11:29:55 2010 @@ -436,7 +436,7 @@ assert res == 42 def test_can_move(self): - TP = lltype.GcArray(lltype.Float) + TP = lltype.GcArray(lltype.UniChar) def func(): return rgc.can_move(lltype.malloc(TP, 1)) assert self.interpret(func, []) == self.GC_CAN_MOVE From arigo at codespeak.net Wed Mar 24 12:08:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 12:08:26 +0100 (CET) Subject: [pypy-svn] r72699 - in pypy/branch/fix-64/pypy/rpython/memory: gc test Message-ID: <20100324110826.37A40282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 12:08:24 2010 New Revision: 72699 Modified: pypy/branch/fix-64/pypy/rpython/memory/gc/generation.py pypy/branch/fix-64/pypy/rpython/memory/gc/hybrid.py pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Log: Revert r72698, and fix the issue more generally by giving small sizes that are expressed in multiples of the word size. Modified: pypy/branch/fix-64/pypy/rpython/memory/gc/generation.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/gc/generation.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/gc/generation.py Wed Mar 24 12:08:24 2010 @@ -8,9 +8,11 @@ from pypy.rlib.objectmodel import free_non_gc_object from pypy.rlib.debug import ll_assert from pypy.rlib.debug import debug_print, debug_start, debug_stop -from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import intmask, LONG_BIT from pypy.rpython.lltypesystem.lloperation import llop +WORD = LONG_BIT // 8 + # The following flag is never set on young objects, i.e. the ones living # in the nursery. It is initially set on all prebuilt and old objects, # and gets cleared by the write_barrier() when we write in them a @@ -47,10 +49,10 @@ nursery_hash_base = -1 def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, - nursery_size=128, - min_nursery_size=128, + nursery_size=32*WORD, + min_nursery_size=32*WORD, auto_nursery_size=False, - space_size=4096, + space_size=1024*WORD, max_space_size=sys.maxint//2+1): SemiSpaceGC.__init__(self, config, chunk_size = chunk_size, space_size = space_size, Modified: pypy/branch/fix-64/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/gc/hybrid.py Wed Mar 24 12:08:24 2010 @@ -1,6 +1,6 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC -from pypy.rpython.memory.gc.generation import GenerationGC +from pypy.rpython.memory.gc.generation import GenerationGC, WORD from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.semispace import GCFLAG_HASHMASK from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS @@ -89,8 +89,8 @@ # condition: large_object <= large_object_gcptrs < min_nursery_size/4 def __init__(self, *args, **kwds): - large_object = kwds.pop('large_object', 24) - large_object_gcptrs = kwds.pop('large_object_gcptrs', 32) + large_object = kwds.pop('large_object', 6*WORD) + large_object_gcptrs = kwds.pop('large_object_gcptrs', 8*WORD) self.generation3_collect_threshold = kwds.pop( 'generation3_collect_threshold', GENERATION3_COLLECT_THRESHOLD) GenerationGC.__init__(self, *args, **kwds) Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/test/test_gc.py Wed Mar 24 12:08:24 2010 @@ -1,7 +1,6 @@ import py import sys -#from pypy.rpython.memory.support import INT_SIZE from pypy.rpython.memory import gcwrapper from pypy.rpython.memory.test import snippet from pypy.rpython.test.test_llinterp import get_interpreter @@ -12,6 +11,10 @@ from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here from pypy.rlib import rgc from pypy.rlib.rstring import StringBuilder +from pypy.rlib.rarithmetic import LONG_BIT + +WORD = LONG_BIT // 8 + def stdout_ignore_ll_functions(msg): strmsg = str(msg) @@ -436,7 +439,7 @@ assert res == 42 def test_can_move(self): - TP = lltype.GcArray(lltype.UniChar) + TP = lltype.GcArray(lltype.Float) def func(): return rgc.can_move(lltype.malloc(TP, 1)) assert self.interpret(func, []) == self.GC_CAN_MOVE @@ -629,7 +632,7 @@ GC_CAN_SHRINK_ARRAY = True class TestGrowingSemiSpaceGC(TestSemiSpaceGC): - GC_PARAMS = {'space_size': 64} + GC_PARAMS = {'space_size': 16*WORD} class TestGenerationalGC(TestSemiSpaceGC): from pypy.rpython.memory.gc.generation import GenerationGC as GCClass @@ -641,7 +644,7 @@ py.test.skip("Not implemented yet") class TestMarkCompactGCGrowing(TestMarkCompactGC): - GC_PARAMS = {'space_size': 64} + GC_PARAMS = {'space_size': 16*WORD} class TestHybridGC(TestGenerationalGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass @@ -716,11 +719,11 @@ GC_CAN_MOVE = False # with this size of heap, stuff gets allocated # in 3rd gen. GC_CANNOT_MALLOC_NONMOVABLE = False - GC_PARAMS = {'space_size': 192, - 'min_nursery_size': 48, - 'nursery_size': 48, - 'large_object': 12, - 'large_object_gcptrs': 12, + GC_PARAMS = {'space_size': 48*WORD, + 'min_nursery_size': 12*WORD, + 'nursery_size': 12*WORD, + 'large_object': 3*WORD, + 'large_object_gcptrs': 3*WORD, 'generation3_collect_threshold': 5, } Modified: pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/test/test_transformed_gc.py Wed Mar 24 12:08:24 2010 @@ -1,6 +1,6 @@ import py import sys -import struct, inspect +import inspect from pypy.translator.c import gc from pypy.annotation import model as annmodel from pypy.annotation import policy as annpolicy @@ -14,8 +14,9 @@ from pypy import conftest from pypy.rlib.rstring import StringBuilder from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.rarithmetic import LONG_BIT -INT_SIZE = struct.calcsize("i") # only for estimates +WORD = LONG_BIT // 8 def rtype(func, inputtypes, specialize=True, gcname='ref', stacklessgc=False, @@ -219,7 +220,7 @@ run, statistics = self.runner("llinterp_lists", statistics=True) run([]) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def define_llinterp_tuples(cls): def malloc_a_lot(): @@ -239,7 +240,7 @@ run, statistics = self.runner("llinterp_tuples", statistics=True) run([]) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def skipdefine_global_list(cls): gl = [] @@ -275,7 +276,7 @@ res = run([100, 0]) assert res == len(''.join([str(x) for x in range(100)])) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def define_nongc_static_root(cls): T1 = lltype.GcStruct("C", ('x', lltype.Signed)) @@ -883,7 +884,7 @@ gcname = "marksweep" class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 @@ -1121,7 +1122,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.marksweep import PrintingMarkSweepGC as GCClass - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 class TestSemiSpaceGC(GenericMovingGCTests): @@ -1131,7 +1132,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass - GC_PARAMS = {'space_size': 2048} + GC_PARAMS = {'space_size': 512*WORD} root_stack_depth = 200 class TestMarkCompactGC(GenericMovingGCTests): @@ -1143,7 +1144,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass - GC_PARAMS = {'space_size': 2048} + GC_PARAMS = {'space_size': 512*WORD} root_stack_depth = 200 class TestGenerationGC(GenericMovingGCTests): @@ -1154,8 +1155,8 @@ class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.generation import GenerationGC as \ GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD} root_stack_depth = 200 def define_weakref_across_minor_collection(cls): @@ -1351,8 +1352,8 @@ self.__ready = False # collecting here is expected GenerationGC._teardown(self) - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 512} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 128*WORD} root_stack_depth = 200 def define_working_nursery(cls): @@ -1382,9 +1383,9 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128, - 'large_object': 32} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD, + 'large_object': 8*WORD} root_stack_depth = 200 def define_ref_from_rawmalloced_to_regular(cls): @@ -1522,7 +1523,7 @@ gcname = "marksweep" class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 class TestHybridTaggedPointerGC(TaggedPointerGCTests): @@ -1532,6 +1533,6 @@ class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.generation import GenerationGC as \ GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD} root_stack_depth = 200 From arigo at codespeak.net Wed Mar 24 12:21:46 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 12:21:46 +0100 (CET) Subject: [pypy-svn] r72700 - in pypy/branch/fix-64/pypy/rlib: . test Message-ID: <20100324112146.E1385282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 12:21:45 2010 New Revision: 72700 Modified: pypy/branch/fix-64/pypy/rlib/rmarshal.py pypy/branch/fix-64/pypy/rlib/test/test_rmarshal.py Log: Fix rlib/rmarshal to work on 64-bit platforms. Add a test. Modified: pypy/branch/fix-64/pypy/rlib/rmarshal.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/rmarshal.py (original) +++ pypy/branch/fix-64/pypy/rlib/rmarshal.py Wed Mar 24 12:21:45 2010 @@ -6,7 +6,7 @@ from pypy.annotation.signature import annotation from pypy.annotation.listdef import ListDef, TooLateForChange from pypy.tool.pairtype import pair, pairtype -from pypy.rlib.rarithmetic import formatd, r_longlong, intmask +from pypy.rlib.rarithmetic import formatd, r_longlong, intmask, LONG_BIT from pypy.rlib.rarithmetic import break_up_float, parts_to_float from pypy.rlib.unroll import unrolling_iterable @@ -151,8 +151,12 @@ add_loader(annmodel.s_Bool, load_bool) def dump_int(buf, x): - buf.append(TYPE_INT) - w_long(buf, x) + # only use TYPE_INT on 32-bit platforms + if LONG_BIT > 32: + dump_longlong(buf, r_longlong(x)) + else: + buf.append(TYPE_INT) + w_long(buf, x) add_dumper(annmodel.SomeInteger(), dump_int) def load_int_nonneg(loader): @@ -163,9 +167,14 @@ add_loader(annmodel.SomeInteger(nonneg=True), load_int_nonneg) def load_int(loader): - if readchr(loader) != TYPE_INT: - raise ValueError("expected an int") - return readlong(loader) + r = readchr(loader) + if LONG_BIT > 32 and r == TYPE_INT64: + x = readlong(loader) & 0xFFFFFFFF + x |= readlong(loader) << 32 + return x + if r == TYPE_INT: + return readlong(loader) + raise ValueError("expected an int") add_loader(annmodel.SomeInteger(), load_int) def dump_longlong(buf, x): Modified: pypy/branch/fix-64/pypy/rlib/test/test_rmarshal.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rmarshal.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rmarshal.py Wed Mar 24 12:21:45 2010 @@ -2,7 +2,7 @@ import marshal from pypy.rlib.rmarshal import * from pypy.annotation import model as annmodel -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT types_that_can_be_none = [ [int], @@ -17,6 +17,10 @@ assert marshal.loads(''.join(buf)) == 5 buf = [] + get_marshaller(int)(buf, -555) + assert marshal.loads(''.join(buf)) == -555 + + buf = [] get_marshaller(float)(buf, 3.25) assert marshal.loads(''.join(buf)) == 3.25 @@ -37,6 +41,15 @@ assert marshal.loads(''.join(buf)) == 0x12380000007 buf = [] + get_marshaller(r_longlong)(buf, r_longlong(-0x12380000007)) + assert marshal.loads(''.join(buf)) == -0x12380000007 + + if LONG_BIT > 32: + buf = [] + get_marshaller(int)(buf, -0x12340000007) + assert marshal.loads(''.join(buf)) == -0x12340000007 + + buf = [] get_marshaller([int])(buf, [2, 5, -7]) assert marshal.loads(''.join(buf)) == [2, 5, -7] @@ -54,6 +67,9 @@ buf = 'i\x05\x00\x00\x00' assert get_unmarshaller(int)(buf) == 5 + buf = 'i\x00\xf0\xff\xff' + assert get_unmarshaller(int)(buf) == -4096 + buf = 'f\x043.25' assert get_unmarshaller(float)(buf) == 3.25 @@ -75,6 +91,16 @@ buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' assert get_unmarshaller(r_longlong)(buf) == 0x12380000007 + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(r_longlong)(buf) == -7566046822028738560L + + if LONG_BIT > 32: + buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' + assert get_unmarshaller(int)(buf) == 0x12380000007 + + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(int)(buf) == -7566046822028738560 + buf = ('[\x03\x00\x00\x00i\x02\x00\x00\x00i\x05\x00\x00\x00' 'i\xf9\xff\xff\xff') assert get_unmarshaller([int])(buf) == [2, 5, -7] @@ -98,10 +124,18 @@ return ''.join(buf) res = interpret(f, []) res = ''.join(res.chars) - assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' - 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' - 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' - 'f\x061e+100') + if LONG_BIT == 32: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' + 'f\x061e+100') + else: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00' + 'I\x05\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'I\x07\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00world' + 'f\x061e+100') def test_llinterp_unmarshal(): from pypy.rpython.test.test_llinterp import interpret From afa at codespeak.net Wed Mar 24 13:46:10 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 13:46:10 +0100 (CET) Subject: [pypy-svn] r72702 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324124610.C2F82282BD6@codespeak.net> Author: afa Date: Wed Mar 24 13:46:09 2010 New Revision: 72702 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: fix arguments passed to the C function Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Wed Mar 24 13:46:09 2010 @@ -45,16 +45,24 @@ @unwrap_spec(ObjSpace, W_Root, Arguments) def cfunction_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) - w_tuple = __args__.unpack_cpy() - ret = self.call(None, w_tuple) + args_w, kw_w = __args__.unpack() + w_args = space.newtuple(args_w) + if kw_w: + raise OperationError(space.w_TypeError, + space.wrap("keywords not yet supported")) + ret = self.call(None, space.newtuple(args_w)) return ret @unwrap_spec(ObjSpace, W_Root, Arguments) def cmethod_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) - w_tuple = __args__.unpack_cpy(1) - w_self = __args__.arguments_w[0] - ret = self.call(w_self, w_tuple) + args_w, kw_w = __args__.unpack() + w_instance = args_w[0] + w_args = space.newtuple(args_w[1:]) + if kw_w: + raise OperationError(space.w_TypeError, + space.wrap("keywords not yet supported")) + ret = self.call(w_instance, w_args) return ret def cmethod_descr_get(space, w_function, w_obj, w_cls=None): From arigo at codespeak.net Wed Mar 24 13:55:28 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 13:55:28 +0100 (CET) Subject: [pypy-svn] r72703 - pypy/branch/fix-64/pypy/rlib/test Message-ID: <20100324125528.5B5AC282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 13:55:27 2010 New Revision: 72703 Modified: pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Log: An obscure failing test. Modified: pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Wed Mar 24 13:55:27 2010 @@ -193,6 +193,11 @@ f2 = rbigint.fromlong(y) assert (x < y) == f1.lt(f2) + def test_ge(self): + f1 = rbigint.fromlong(13) + f2 = rbigint.fromlong(13) + assert f1.ge(f2) + def test_int_conversion(self): f1 = rbigint.fromlong(12332) f2 = rbigint.fromint(12332) From arigo at codespeak.net Wed Mar 24 14:03:34 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 14:03:34 +0100 (CET) Subject: [pypy-svn] r72704 - in pypy/branch/fix-64/pypy/rlib: . test Message-ID: <20100324130334.F35A4282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 14:03:33 2010 New Revision: 72704 Modified: pypy/branch/fix-64/pypy/rlib/rbigint.py pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Log: Bah, rbigint(5).ge(rbigint(5)) => False. What is not tested is broken. Modified: pypy/branch/fix-64/pypy/rlib/rbigint.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/rbigint.py (original) +++ pypy/branch/fix-64/pypy/rlib/rbigint.py Wed Mar 24 14:03:33 2010 @@ -272,13 +272,13 @@ return False def le(self, other): - return self.lt(other) or self.eq(other) + return not other.lt(self) def gt(self, other): - return other.le(self) + return other.lt(self) def ge(self, other): - return other.lt(self) + return not self.lt(other) def hash(self): return _hash(self) Modified: pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Wed Mar 24 14:03:33 2010 @@ -193,10 +193,13 @@ f2 = rbigint.fromlong(y) assert (x < y) == f1.lt(f2) - def test_ge(self): - f1 = rbigint.fromlong(13) - f2 = rbigint.fromlong(13) - assert f1.ge(f2) + def test_order(self): + f6 = rbigint.fromint(6) + f7 = rbigint.fromint(7) + assert (f6.lt(f6), f6.lt(f7), f7.lt(f6)) == (0,1,0) + assert (f6.le(f6), f6.le(f7), f7.le(f6)) == (1,1,0) + assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1) + assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1) def test_int_conversion(self): f1 = rbigint.fromlong(12332) From arigo at codespeak.net Wed Mar 24 14:10:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 14:10:42 +0100 (CET) Subject: [pypy-svn] r72705 - in pypy/branch/fix-64/pypy/objspace/std: . test Message-ID: <20100324131042.6A677282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 14:10:40 2010 New Revision: 72705 Modified: pypy/branch/fix-64/pypy/objspace/std/floatobject.py pypy/branch/fix-64/pypy/objspace/std/test/test_floatobject.py Log: Fix for code like "62-bit-int == float", on 64-bit platforms where casting the int to a float might loose precision. Done with more verbose but more regular code in floatobject. Drawback: at app-level, "5 .__eq__(3.4)" now returns False instead of NotImplemented. Do we care at all? Modified: pypy/branch/fix-64/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/fix-64/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/fix-64/pypy/objspace/std/floatobject.py Wed Mar 24 14:10:40 2010 @@ -1,9 +1,11 @@ +import operator, new from pypy.objspace.std.objspace import * from pypy.interpreter import gateway from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT +from pypy.rlib.rbigint import rbigint import math from pypy.objspace.std.intobject import W_IntObject @@ -88,82 +90,115 @@ s = formatd("%.12g", x) return space.wrap(should_not_look_like_an_int(s)) +# ____________________________________________________________ +# A mess to handle all cases of float comparison without relying +# on delegation, which can unfortunately loose precision when +# casting an int or a long to a float. + +def list_compare_funcs(declarator): + for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: + func, name = declarator(op) + globals()[name] = func_with_new_name(func, name) + +def _reverse(opname): + if opname[0] == 'l': return 'g' + opname[1:] + elif opname[0] == 'g': return 'l' + opname[1:] + else: return opname -def declare_new_float_comparison(opname): - import operator - from pypy.tool.sourcetools import func_with_new_name - op = getattr(operator, opname) - def f(space, w_int1, w_int2): - i = w_int1.floatval - j = w_int2.floatval - return space.newbool(op(i, j)) - name = opname + "__Float_Float" - return func_with_new_name(f, name), name - -for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: - func, name = declare_new_float_comparison(op) - globals()[name] = func - -# for overflowing comparisons between longs and floats -# XXX we might have to worry (later) about eq__Float_Int, for the case -# where int->float conversion may lose precision :-( -def eq__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x) or math.floor(x) != x: - return space.w_False - try: - w_long1 = W_LongObject.fromfloat(x) - except OverflowError: - return space.w_False - return space.eq(w_long1, w_long2) - -def eq__Long_Float(space, w_long1, w_float2): - return eq__Float_Long(space, w_float2, w_long1) - -def ne__Float_Long(space, w_float1, w_long2): - return space.not_(eq__Float_Long(space, w_float1, w_long2)) - -def ne__Long_Float(space, w_long1, w_float2): - return space.not_(eq__Float_Long(space, w_float2, w_long1)) - -def lt__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x): - return space.newbool(x < 0.0) - x_floor = math.floor(x) - try: - w_long1 = W_LongObject.fromfloat(x_floor) - except OverflowError: - return space.newbool(x < 0.0) - return space.lt(w_long1, w_long2) - -def lt__Long_Float(space, w_long1, w_float2): - return space.not_(le__Float_Long(space, w_float2, w_long1)) -def le__Float_Long(space, w_float1, w_long2): - # XXX it's naive anyway - if space.is_true(space.lt(w_float1, w_long2)): - return space.w_True +def declare_compare_bigint(opname): + """Return a helper function that implements a float-bigint comparison.""" + op = getattr(operator, opname) + # + if opname == 'eq' or opname == 'ne': + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1) or math.floor(f1) != f1: + return opname == 'ne' + b1 = rbigint.fromfloat(f1) + res = b1.eq(b2) + if opname == 'ne': + res = not res + return res else: - return space.eq(w_float1, w_long2) + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1): + return op(f1, 0.0) + if opname == 'gt' or opname == 'le': + # 'float > long' <==> 'ceil(float) > long' + # 'float <= long' <==> 'ceil(float) <= long' + f1 = math.ceil(f1) + else: + # 'float < long' <==> 'floor(float) < long' + # 'float >= long' <==> 'floor(float) >= long' + f1 = math.floor(f1) + b1 = rbigint.fromfloat(f1) + return getattr(b1, opname)(b2) + # + return do_compare_bigint, 'compare_bigint_' + opname +list_compare_funcs(declare_compare_bigint) -def le__Long_Float(space, w_long1, w_float2): - return space.not_(lt__Float_Long(space, w_float2, w_long1)) -def gt__Float_Long(space, w_float1, w_long2): - return space.not_(le__Float_Long(space, w_float1, w_long2)) +def declare_cmp_float_float(opname): + op = getattr(operator, opname) + def f(space, w_float1, w_float2): + f1 = w_float1.floatval + f2 = w_float2.floatval + return space.newbool(op(f1, f2)) + return f, opname + "__Float_Float" +list_compare_funcs(declare_cmp_float_float) -def gt__Long_Float(space, w_long1, w_float2): - return lt__Float_Long(space, w_float2, w_long1) +def declare_cmp_float_int(opname): + op = getattr(operator, opname) + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_int2): + f1 = w_float1.floatval + i2 = w_int2.intval + f2 = float(i2) + if LONG_BIT > 32 and int(f2) != i2: + res = compare(f1, rbigint.fromint(i2)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Float_Int" +list_compare_funcs(declare_cmp_float_int) + +def declare_cmp_float_long(opname): + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_long2): + f1 = w_float1.floatval + b2 = w_long2.num + return space.newbool(compare(f1, b2)) + return f, opname + "__Float_Long" +list_compare_funcs(declare_cmp_float_long) -def ge__Float_Long(space, w_float1, w_long2): - return space.not_(lt__Float_Long(space, w_float1, w_long2)) +def declare_cmp_int_float(opname): + op = getattr(operator, opname) + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_int1, w_float2): + f2 = w_float2.floatval + i1 = w_int1.intval + f1 = float(i1) + if LONG_BIT > 32 and int(f1) != i1: + res = revcompare(f2, rbigint.fromint(i1)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Int_Float" +list_compare_funcs(declare_cmp_int_float) + +def declare_cmp_long_float(opname): + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_long1, w_float2): + f2 = w_float2.floatval + b1 = w_long1.num + return space.newbool(revcompare(f2, b1)) + return f, opname + "__Long_Float" +list_compare_funcs(declare_cmp_long_float) -def ge__Long_Float(space, w_long1, w_float2): - return le__Float_Long(space, w_float2, w_long1) +# ____________________________________________________________ def hash__Float(space, w_value): return space.wrap(_hash_float(space, w_value.floatval)) Modified: pypy/branch/fix-64/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/branch/fix-64/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/branch/fix-64/pypy/objspace/std/test/test_floatobject.py Wed Mar 24 14:10:40 2010 @@ -212,6 +212,8 @@ assert 13 <= 13.01 def test_comparison_more(self): + import sys + is_pypy = '__pypy__' in sys.builtin_module_names infinity = 1e200*1e200 nan = infinity/infinity for x in (123, 1 << 30, @@ -239,12 +241,27 @@ assert ((x + 1) > float(x)) assert not ((x + 1) < float(x)) # - #assert not (x == nan) - #assert not (x >= nan) - #assert not (x <= nan) - #assert (x != nan) - #assert not (x > nan) - #assert not (x < nan) + assert not (x == infinity) + assert not (x >= infinity) + assert (x <= infinity) + assert (x != infinity) + assert not (x > infinity) + assert (x < infinity) + # + assert not (x == -infinity) + assert (x >= -infinity) + assert not (x <= -infinity) + assert (x != -infinity) + assert (x > -infinity) + assert not (x < -infinity) + # + if is_pypy: + assert not (x == nan) + assert not (x >= nan) + assert not (x <= nan) + assert (x != nan) + assert not (x > nan) + assert not (x < nan) # assert (float(x) == x) assert (float(x) <= x) @@ -267,19 +284,35 @@ assert (float(x) < (x + 1)) assert not (float(x) > (x + 1)) # - #assert not (nan == x) - #assert not (nan <= x) - #assert not (nan >= x) - #assert (nan != x) - #assert not (nan < x) - #assert not (nan > x) + assert not (infinity == x) + assert (infinity >= x) + assert not (infinity <= x) + assert (infinity != x) + assert (infinity > x) + assert not (infinity < x) + # + assert not (-infinity == x) + assert not (-infinity >= x) + assert (-infinity <= x) + assert (-infinity != x) + assert not (-infinity > x) + assert (-infinity < x) + # + if is_pypy: + assert not (nan == x) + assert not (nan <= x) + assert not (nan >= x) + assert (nan != x) + assert not (nan < x) + assert not (nan > x) def test_multimethod_slice(self): assert 5 .__add__(3.14) is NotImplemented assert 3.25 .__add__(5) == 8.25 - if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent - assert 5 .__eq__(3.14) is NotImplemented - assert 3.14 .__eq__(5) is False + # xxx we are also a bit inconsistent about the following + #if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent + # assert 5 .__eq__(3.14) is NotImplemented + # assert 3.14 .__eq__(5) is False #if hasattr(long, '__eq__'): # for py.test -A: CPython is inconsistent # assert 5L .__eq__(3.14) is NotImplemented # assert 3.14 .__eq__(5L) is False From arigo at codespeak.net Wed Mar 24 14:17:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 14:17:26 +0100 (CET) Subject: [pypy-svn] r72706 - in pypy/branch/fix-64/pypy: jit/backend/x86/test translator/c/gcc/test Message-ID: <20100324131726.E850D282BD6@codespeak.net> Author: arigo Date: Wed Mar 24 14:17:25 2010 New Revision: 72706 Added: pypy/branch/fix-64/pypy/translator/c/gcc/test/conftest.py - copied, changed from r72695, pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py Modified: pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py Log: Tweak the conftest. By skipping at the level of each module instead of at the level of the directory, we avoid crashes when we try to say "py.test test_somefile.py". Modified: pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py ============================================================================== --- pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py (original) +++ pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py Wed Mar 24 14:17:25 2010 @@ -1,9 +1,9 @@ import py from pypy.jit.backend import detect_cpu -class Directory(py.test.collect.Directory): +class Module(py.test.collect.Module): def collect(self): cpu = detect_cpu.autodetect() if cpu != 'x86': py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) - return super(Directory, self).collect() + return super(Module, self).collect() Copied: pypy/branch/fix-64/pypy/translator/c/gcc/test/conftest.py (from r72695, pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py) ============================================================================== --- pypy/branch/fix-64/pypy/jit/backend/x86/test/conftest.py (original) +++ pypy/branch/fix-64/pypy/translator/c/gcc/test/conftest.py Wed Mar 24 14:17:25 2010 @@ -1,9 +1,9 @@ import py from pypy.jit.backend import detect_cpu -class Directory(py.test.collect.Directory): +class Module(py.test.collect.Module): def collect(self): cpu = detect_cpu.autodetect() if cpu != 'x86': py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) - return super(Directory, self).collect() + return super(Module, self).collect() From cfbolz at codespeak.net Wed Mar 24 14:40:49 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 24 Mar 2010 14:40:49 +0100 (CET) Subject: [pypy-svn] r72707 - pypy/branch/type-celldict Message-ID: <20100324134049.07F48282BDC@codespeak.net> Author: cfbolz Date: Wed Mar 24 14:40:48 2010 New Revision: 72707 Removed: pypy/branch/type-celldict/ Log: kill, contains no useful things From jandem at codespeak.net Wed Mar 24 15:18:29 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Wed, 24 Mar 2010 15:18:29 +0100 (CET) Subject: [pypy-svn] r72709 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100324141829.39DB5282BDC@codespeak.net> Author: jandem Date: Wed Mar 24 15:18:27 2010 New Revision: 72709 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/object.py Log: Add PyObject_{IsTrue, Not}, with tests Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 24 15:18:27 2010 @@ -394,4 +394,7 @@ /* PyPy internal ----------------------------------- */ int PyPyType_Register(PyTypeObject *); +int PyObject_IsTrue(PyObject *); +int PyObject_Not(PyObject *); + #endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 24 15:18:27 2010 @@ -26,3 +26,10 @@ obj_voidp = rffi.cast(rffi.VOIDP_real, obj) generic_cpy_call(space, pto.c_tp_free, obj_voidp) + at cpython_api([PyObject], rffi.INT_real) +def PyObject_IsTrue(space, w_obj): + return space.is_true(w_obj) + + at cpython_api([PyObject], rffi.INT_real) +def PyObject_Not(space, w_obj): + return space.is_true(space.not_(w_obj)) Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Wed Mar 24 15:18:27 2010 @@ -0,0 +1,31 @@ +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +import py +import sys + +class AppTestObject(AppTestCpythonExtensionBase): + def test_IsTrue(self): + module = self.import_extension('foo', [ + ("test_IsTrue", "METH_VARARGS", + """ + PyObject* arg = PyTuple_GetItem(args, 0); + return PyBool_FromLong(PyObject_IsTrue(arg)); + """), + ]) + assert module.test_IsTrue(True) + assert module.test_IsTrue(1.0) + assert not module.test_IsTrue(False) + assert not module.test_IsTrue(0) + + def test_Not(self): + module = self.import_extension('foo', [ + ("test_Not", "METH_VARARGS", + """ + PyObject* arg = PyTuple_GetItem(args, 0); + return PyBool_FromLong(PyObject_Not(arg)); + """), + ]) + assert module.test_Not(False) + assert module.test_Not(0) + assert not module.test_Not(True) + assert not module.test_Not(3.14) From arigo at codespeak.net Wed Mar 24 15:27:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:27:55 +0100 (CET) Subject: [pypy-svn] r72710 - pypy/branch/fix-64/pypy/objspace/std/test Message-ID: <20100324142755.87FAA282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:27:54 2010 New Revision: 72710 Modified: pypy/branch/fix-64/pypy/objspace/std/test/test_longobject.py Log: Improve the failing test. Modified: pypy/branch/fix-64/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/branch/fix-64/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/branch/fix-64/pypy/objspace/std/test/test_longobject.py Wed Mar 24 15:27:54 2010 @@ -60,37 +60,79 @@ assert a == 3L def test_compare(self): - BIG = 1L << 9999 - assert 0 == 0L - assert not (0 != 0L) - assert 0L == 0 - assert not (0L != 0) - assert not (0 == BIG) - assert 0 != BIG - assert not (BIG == 0) - assert BIG != 0 - assert not (0L == BIG) - assert 0L != BIG - assert 0 <= 0L - assert not (0 < 0L) - assert 0 <= BIG - assert 0 < BIG - assert not (BIG <= 0) - assert not (BIG < 0) - assert 0L <= 0L - assert not (0L < 0L) - assert 0L <= BIG - assert 0L < BIG - assert not (BIG <= 0L) - assert not (BIG < 0L) - assert not (0 <= -BIG) - assert not (0 < -BIG) - assert -BIG <= 0 - assert -BIG < 0 - assert not (0L <= -BIG) - assert not (0L < -BIG) - assert -BIG <= 0L - assert -BIG < 0L + for BIG in (1L, 1L << 62, 1L << 9999): + assert 0 == 0L + assert not (0 != 0L) + assert 0L == 0 + assert not (0L != 0) + assert not (0 == BIG) + assert 0 != BIG + assert not (BIG == 0) + assert BIG != 0 + assert not (0L == BIG) + assert 0L != BIG + assert 0 <= 0L + assert not (0 < 0L) + assert 0 <= BIG + assert 0 < BIG + assert not (BIG <= 0) + assert not (BIG < 0) + assert 0L <= 0L + assert not (0L < 0L) + assert 0L <= BIG + assert 0L < BIG + assert not (BIG <= 0L) + assert not (BIG < 0L) + assert not (0 <= -BIG) + assert not (0 < -BIG) + assert -BIG <= 0 + assert -BIG < 0 + assert not (0L <= -BIG) + assert not (0L < -BIG) + assert -BIG <= 0L + assert -BIG < 0L + # + assert not (BIG < int(BIG)) + assert (BIG <= int(BIG)) + assert (BIG == int(BIG)) + assert not (BIG != int(BIG)) + assert not (BIG > int(BIG)) + assert (BIG >= int(BIG)) + # + assert (BIG < int(BIG)+1) + assert (BIG <= int(BIG)+1) + assert not (BIG == int(BIG)+1) + assert (BIG != int(BIG)+1) + assert not (BIG > int(BIG)+1) + assert not (BIG >= int(BIG)+1) + # + assert not (BIG < int(BIG)-1) + assert not (BIG <= int(BIG)-1) + assert not (BIG == int(BIG)-1) + assert (BIG != int(BIG)-1) + assert (BIG > int(BIG)-1) + assert (BIG >= int(BIG)-1) + # + assert not (int(BIG) < BIG) + assert (int(BIG) <= BIG) + assert (int(BIG) == BIG) + assert not (int(BIG) != BIG) + assert not (int(BIG) > BIG) + assert (int(BIG) >= BIG) + # + assert not (int(BIG)+1 < BIG) + assert not (int(BIG)+1 <= BIG) + assert not (int(BIG)+1 == BIG) + assert (int(BIG)+1 != BIG) + assert (int(BIG)+1 > BIG) + assert (int(BIG)+1 >= BIG) + # + assert (int(BIG)-1 < BIG) + assert (int(BIG)-1 <= BIG) + assert not (int(BIG)-1 == BIG) + assert (int(BIG)-1 != BIG) + assert not (int(BIG)-1 > BIG) + assert not (int(BIG)-1 >= BIG) def test_conversion(self): class long2(long): From afa at codespeak.net Wed Mar 24 15:30:14 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 15:30:14 +0100 (CET) Subject: [pypy-svn] r72711 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324143014.033CA282BDC@codespeak.net> Author: afa Date: Wed Mar 24 15:30:13 2010 New Revision: 72711 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py Log: tiny optimization (space.not_ already calls is_true) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 24 15:30:13 2010 @@ -32,4 +32,4 @@ @cpython_api([PyObject], rffi.INT_real) def PyObject_Not(space, w_obj): - return space.is_true(space.not_(w_obj)) + return not space.is_true(w_obj) From arigo at codespeak.net Wed Mar 24 15:31:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:31:02 +0100 (CET) Subject: [pypy-svn] r72712 - pypy/branch/fix-64/pypy/objspace/std Message-ID: <20100324143102.55B48282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:31:00 2010 New Revision: 72712 Modified: pypy/branch/fix-64/pypy/objspace/std/longobject.py Log: Brute-force fix of the failure: just list all cases. Modified: pypy/branch/fix-64/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/fix-64/pypy/objspace/std/longobject.py (original) +++ pypy/branch/fix-64/pypy/objspace/std/longobject.py Wed Mar 24 15:31:00 2010 @@ -120,11 +120,46 @@ def str__Long(space, w_long): return space.wrap(w_long.num.str()) -def eq__Long_Long(space, w_long1, w_long2): - return space.newbool(w_long1.num.eq(w_long2.num)) def lt__Long_Long(space, w_long1, w_long2): return space.newbool(w_long1.num.lt(w_long2.num)) +def le__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.le(w_long2.num)) +def eq__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.eq(w_long2.num)) +def ne__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ne(w_long2.num)) +def gt__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.gt(w_long2.num)) +def ge__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ge(w_long2.num)) + +def lt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.lt(rbigint.fromint(w_int2.intval))) +def le__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.le(rbigint.fromint(w_int2.intval))) +def eq__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.eq(rbigint.fromint(w_int2.intval))) +def ne__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ne(rbigint.fromint(w_int2.intval))) +def gt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.gt(rbigint.fromint(w_int2.intval))) +def ge__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ge(rbigint.fromint(w_int2.intval))) + +def lt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).lt(w_long2.num)) +def le__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).le(w_long2.num)) +def eq__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).eq(w_long2.num)) +def ne__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ne(w_long2.num)) +def gt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).gt(w_long2.num)) +def ge__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ge(w_long2.num)) + def hash__Long(space, w_value): return space.wrap(w_value.num.hash()) From arigo at codespeak.net Wed Mar 24 15:44:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:44:06 +0100 (CET) Subject: [pypy-svn] r72714 - pypy/branch/fix-64/pypy/rlib/test Message-ID: <20100324144406.E178B282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:44:05 2010 New Revision: 72714 Modified: pypy/branch/fix-64/pypy/rlib/test/test_rarithmetic.py Log: Bug. Modified: pypy/branch/fix-64/pypy/rlib/test/test_rarithmetic.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rarithmetic.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rarithmetic.py Wed Mar 24 15:44:05 2010 @@ -197,6 +197,10 @@ x = intmask(tp(5)) assert (type(x), x) == (int, 5) +def test_bug_creating_r_int(): + minint = -sys.maxint-1 + assert r_int(r_int(minint)) == minint + def test_ovfcheck(): one = 1 x = sys.maxint From arigo at codespeak.net Wed Mar 24 15:46:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:46:40 +0100 (CET) Subject: [pypy-svn] r72716 - pypy/branch/fix-64/pypy/rlib Message-ID: <20100324144640.A6351282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:46:39 2010 New Revision: 72716 Modified: pypy/branch/fix-64/pypy/rlib/rarithmetic.py Log: Fix for r72714. Modified: pypy/branch/fix-64/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/rarithmetic.py (original) +++ pypy/branch/fix-64/pypy/rlib/rarithmetic.py Wed Mar 24 15:46:39 2010 @@ -307,7 +307,7 @@ if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) if val < 0: - val = - ((-val) & klass.MASK) + val = ~ ((~val) & klass.MASK) return super(signed_int, klass).__new__(klass, val) typemap = {} From arigo at codespeak.net Wed Mar 24 15:47:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:47:33 +0100 (CET) Subject: [pypy-svn] r72717 - in pypy/branch/fix-64/pypy/rlib: . test Message-ID: <20100324144733.45B13282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:47:31 2010 New Revision: 72717 Modified: pypy/branch/fix-64/pypy/rlib/rbigint.py pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Log: Fix tests. Modified: pypy/branch/fix-64/pypy/rlib/rbigint.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/rbigint.py (original) +++ pypy/branch/fix-64/pypy/rlib/rbigint.py Wed Mar 24 15:47:31 2010 @@ -49,6 +49,7 @@ class rbigint(object): """This is a reimplementation of longs using a list of digits.""" + # XXX relace the list of ints with a list of rffi.INTs, maybe def __init__(self, digits=None, sign=0): if digits is None or len(digits) == 0: Modified: pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rbigint.py Wed Mar 24 15:47:31 2010 @@ -106,7 +106,7 @@ assert rbigint.fromrarith_int(r_uint(17)).eq(rbigint([17], 1)) assert rbigint.fromrarith_int(r_uint(BASE-1)).eq(rbigint([intmask(BASE-1)], 1)) assert rbigint.fromrarith_int(r_uint(BASE)).eq(rbigint([0, 1], 1)) - assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) + #assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) assert rbigint.fromrarith_int(r_uint(sys.maxint)).eq( rbigint.fromint(sys.maxint)) assert rbigint.fromrarith_int(r_uint(sys.maxint+1)).eq( @@ -473,9 +473,12 @@ def test_args_from_rarith_int(self): from pypy.rpython.tool.rfficache import platform + from pypy.rlib.rarithmetic import r_int classlist = platform.numbertype_to_rclass.values() fnlist = [] for r in classlist: + if r is r_int: # and also r_longlong on 64-bit + continue if r is int: mask = sys.maxint*2+1 signed = True From arigo at codespeak.net Wed Mar 24 15:49:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:49:47 +0100 (CET) Subject: [pypy-svn] r72718 - pypy/branch/fix-64/pypy/rlib/test Message-ID: <20100324144947.444E9282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:49:45 2010 New Revision: 72718 Modified: pypy/branch/fix-64/pypy/rlib/test/test_rstruct.py Log: Fix test. Modified: pypy/branch/fix-64/pypy/rlib/test/test_rstruct.py ============================================================================== --- pypy/branch/fix-64/pypy/rlib/test/test_rstruct.py (original) +++ pypy/branch/fix-64/pypy/rlib/test/test_rstruct.py Wed Mar 24 15:49:45 2010 @@ -1,12 +1,14 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.rstruct.runpack import runpack +from pypy.rlib.rarithmetic import LONG_BIT import struct class BaseTestRStruct(BaseRtypingTest): def test_unpack(self): + pad = '\x00' * (LONG_BIT//8-1) # 3 or 7 null bytes def fn(): - return runpack('sll', 'a\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00')[1] + return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1] assert fn() == 3 assert self.interpret(fn, []) == 3 From arigo at codespeak.net Wed Mar 24 15:52:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:52:32 +0100 (CET) Subject: [pypy-svn] r72719 - pypy/branch/fix-64/pypy/rpython/memory/gc/test Message-ID: <20100324145232.74E07282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:52:30 2010 New Revision: 72719 Modified: pypy/branch/fix-64/pypy/rpython/memory/gc/test/test_direct.py Log: Fix test. Modified: pypy/branch/fix-64/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/branch/fix-64/pypy/rpython/memory/gc/test/test_direct.py Wed Mar 24 15:52:30 2010 @@ -9,6 +9,9 @@ import py from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder +from pypy.rlib.rarithmetic import LONG_BIT + +WORD = LONG_BIT // 8 ADDR_ARRAY = lltype.Array(llmemory.Address) S = lltype.GcForwardReference() @@ -378,11 +381,11 @@ class TestHybridGC(TestGenerationGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass - GC_PARAMS = {'space_size': 192, - 'min_nursery_size': 48, - 'nursery_size': 48, - 'large_object': 12, - 'large_object_gcptrs': 12, + GC_PARAMS = {'space_size': 48*WORD, + 'min_nursery_size': 12*WORD, + 'nursery_size': 12*WORD, + 'large_object': 3*WORD, + 'large_object_gcptrs': 3*WORD, 'generation3_collect_threshold': 5, } From arigo at codespeak.net Wed Mar 24 15:57:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 15:57:31 +0100 (CET) Subject: [pypy-svn] r72720 - in pypy/branch/fix-64/pypy/translator/c: . src test Message-ID: <20100324145731.45783282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 15:57:29 2010 New Revision: 72720 Modified: pypy/branch/fix-64/pypy/translator/c/node.py pypy/branch/fix-64/pypy/translator/c/src/exception.h pypy/branch/fix-64/pypy/translator/c/test/test_exception.py Log: Merge r72589:72591 from the trunk. Modified: pypy/branch/fix-64/pypy/translator/c/node.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/node.py (original) +++ pypy/branch/fix-64/pypy/translator/c/node.py Wed Mar 24 15:57:29 2010 @@ -926,9 +926,10 @@ import types, py if isinstance(value, (type, types.ClassType)): if (issubclass(value, BaseException) and - (value.__module__ == 'exceptions' - or value is py.code._AssertionError)): + value.__module__ == 'exceptions'): return 'PyExc_' + value.__name__ + if value is py.code._AssertionError: + return 'PyExc_AssertionError' raise Exception("don't know how to simply render py object: %r" % (value, )) Modified: pypy/branch/fix-64/pypy/translator/c/src/exception.h ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/src/exception.h (original) +++ pypy/branch/fix-64/pypy/translator/c/src/exception.h Wed Mar 24 15:57:29 2010 @@ -99,14 +99,18 @@ assert(RPyExceptionOccurred()); assert(!PyErr_Occurred()); clsname = RPyFetchExceptionType()->ov_name->items; - pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); - if (pycls != NULL && PyExceptionClass_Check(pycls) && - PyObject_IsSubclass(pycls, PyExc_Exception)) { - v = NULL; + v = NULL; + if (strcmp(clsname, "AssertionError") == 0) { + /* workaround against the py lib's BuiltinAssertionError */ + pycls = PyExc_AssertionError; } else { - pycls = PyExc_Exception; /* XXX RPythonError */ - v = PyString_FromString(clsname); + pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); + if (pycls == NULL || !PyExceptionClass_Check(pycls) || + !PyObject_IsSubclass(pycls, PyExc_Exception)) { + pycls = PyExc_Exception; /* XXX RPythonError */ + v = PyString_FromString(clsname); + } } Py_INCREF(pycls); tb = NULL; Modified: pypy/branch/fix-64/pypy/translator/c/test/test_exception.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_exception.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_exception.py Wed Mar 24 15:57:29 2010 @@ -121,30 +121,16 @@ def testfn(n): assert n >= 0 - # big confusion with py.test's AssertionError handling here... - # some hacks to try to disable it for the current test. - saved = no_magic() - try: - f1 = getcompiled(testfn, [int]) - res = f1(0) - assert res is None, repr(res) - res = f1(42) - assert res is None, repr(res) - py.test.raises(AssertionError, f1, -2) - finally: - restore_magic(saved) - -def no_magic(): - import __builtin__ - try: - py.magic.revert(__builtin__, 'AssertionError') - return True - except ValueError: - return False - -def restore_magic(saved): - if saved: - py.magic.invoke(assertion=True) + f1 = getcompiled(testfn, [int]) + res = f1(0) + assert res is None, repr(res) + res = f1(42) + assert res is None, repr(res) + e = py.test.raises(Exception, f1, -2) + assert e.type.__name__ == 'AssertionError' + # ^^^ indirection, because we really want + # the original AssertionError and not the + # one patched by the py lib def test_reraise_exception(): From arigo at codespeak.net Wed Mar 24 16:01:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 16:01:03 +0100 (CET) Subject: [pypy-svn] r72721 - in pypy/trunk/pypy: interpreter interpreter/test jit/backend/llsupport jit/backend/x86/test module/_socket module/_socket/test module/posix module/posix/test objspace/std objspace/std/test rlib rlib/test rpython/lltypesystem rpython/lltypesystem/test rpython/memory/gc rpython/memory/gc/test rpython/memory/test translator/c translator/c/gcc/test translator/c/src translator/c/test Message-ID: <20100324150103.4497F282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 16:01:00 2010 New Revision: 72721 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/test/test_gateway.py pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/x86/test/conftest.py pypy/trunk/pypy/module/_socket/interp_func.py pypy/trunk/pypy/module/_socket/test/test_sock_app.py pypy/trunk/pypy/module/posix/interp_posix.py pypy/trunk/pypy/module/posix/test/test_posix2.py pypy/trunk/pypy/objspace/std/floatobject.py pypy/trunk/pypy/objspace/std/longobject.py pypy/trunk/pypy/objspace/std/test/test_floatobject.py pypy/trunk/pypy/objspace/std/test/test_longobject.py pypy/trunk/pypy/rlib/rarithmetic.py pypy/trunk/pypy/rlib/rbigint.py pypy/trunk/pypy/rlib/rmarshal.py pypy/trunk/pypy/rlib/rstack.py pypy/trunk/pypy/rlib/test/test_rarithmetic.py pypy/trunk/pypy/rlib/test/test_rbigint.py pypy/trunk/pypy/rlib/test/test_rmarshal.py pypy/trunk/pypy/rlib/test/test_rstruct.py pypy/trunk/pypy/rpython/lltypesystem/llgroup.py pypy/trunk/pypy/rpython/lltypesystem/test/test_llgroup.py pypy/trunk/pypy/rpython/memory/gc/generation.py pypy/trunk/pypy/rpython/memory/gc/hybrid.py pypy/trunk/pypy/rpython/memory/gc/test/test_direct.py pypy/trunk/pypy/rpython/memory/test/test_gc.py pypy/trunk/pypy/rpython/memory/test/test_transformed_gc.py pypy/trunk/pypy/translator/c/gcc/test/conftest.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/primitive.py pypy/trunk/pypy/translator/c/src/llgroup.h pypy/trunk/pypy/translator/c/test/test_lltyped.py Log: Merge the branch/fix-64 into trunk: first round of fixing test failures that show on a 64-bit machine. Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Wed Mar 24 16:01:00 2010 @@ -9,11 +9,14 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer +from pypy.rlib.rarithmetic import r_uint from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +UINT_MAX_32_BITS = r_uint(4294967295) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -1095,6 +1098,24 @@ self.wrap("expected a non-negative integer")) return value + def c_int_w(self, w_obj): + # Like space.int_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.int_w(w_obj) + if value < -2147483647-1 or value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit integer")) + return value + + def c_uint_w(self, w_obj): + # Like space.uint_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.uint_w(w_obj) + if value > UINT_MAX_32_BITS: + raise OperationError(self.w_OverflowError, + self.wrap("expected an unsigned 32-bit 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 Wed Mar 24 16:01:00 2010 @@ -126,6 +126,12 @@ def visit_nonnegint(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_c_int(self, el, app_sig): + self.checked_space_method(el, app_sig) + + def visit_c_uint(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() @@ -230,6 +236,12 @@ def visit_nonnegint(self, typ): self.run_args.append("space.nonnegint_w(%s)" % (self.scopenext(),)) + def visit_c_int(self, typ): + self.run_args.append("space.c_int_w(%s)" % (self.scopenext(),)) + + def visit_c_uint(self, typ): + self.run_args.append("space.c_uint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -348,6 +360,12 @@ def visit_nonnegint(self, typ): self.unwrap.append("space.nonnegint_w(%s)" % (self.nextarg(),)) + def visit_c_int(self, typ): + self.unwrap.append("space.c_int_w(%s)" % (self.nextarg(),)) + + def visit_c_uint(self, typ): + self.unwrap.append("space.c_uint_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 Wed Mar 24 16:01:00 2010 @@ -197,6 +197,40 @@ space.raises_w(space.w_ValueError, space.call_function, w_app_g, space.wrap(-1)) + def test_interp2app_unwrap_spec_c_int(self): + from pypy.rlib.rarithmetic import r_longlong + space = self.space + w = space.wrap + def g(space, x): + return space.wrap(x + 6) + app_g = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_int']) + app_ug = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_uint']) + assert app_ug is not app_g + w_app_g = space.wrap(app_g) + w_app_ug = space.wrap(app_ug) + # + assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(-0x80000001))) + # + assert self.space.eq_w(space.call_function(w_app_ug, space.wrap(7)), + space.wrap(13)) + assert self.space.eq_w(space.call_function(w_app_ug, + space.wrap(0x7FFFFFFF)), + space.wrap(r_longlong(0x7FFFFFFF+6))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ug, space.wrap(-1)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ug, + space.wrap(r_longlong(0x100000000))) + def test_interp2app_unwrap_spec_args_w(self): space = self.space w = space.wrap Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Wed Mar 24 16:01:00 2010 @@ -2,6 +2,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import fatalerror from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr +from pypy.rpython.lltypesystem import llgroup from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -309,7 +310,7 @@ # if convenient for the backend, we also compute the info about # the flag as (byte-offset, single-byte-flag). import struct - value = struct.pack("i", self.jit_wb_if_flag) + value = struct.pack("l", self.jit_wb_if_flag) assert value.count('\x00') == len(value) - 1 # only one byte is != 0 i = 0 while value[i] == '\x00': i += 1 @@ -372,8 +373,8 @@ # make a malloc function, with three arguments def malloc_basic(size, tid): - type_id = llop.extract_ushort(rffi.USHORT, tid) - has_finalizer = bool(tid & (1<<16)) + type_id = llop.extract_ushort(llgroup.HALFWORD, tid) + has_finalizer = bool(tid & (1< integer Convert a 16-bit integer from network to host byte order. """ return space.wrap(rsocket.ntohs(x)) -ntohs.unwrap_spec = [ObjSpace, int] +ntohs.unwrap_spec = [ObjSpace, r_uint] -def ntohl(space, w_x): +def ntohl(space, x): """ntohl(integer) -> integer Convert a 32-bit integer from network to host byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.ntohl(x)) -ntohl.unwrap_spec = [ObjSpace, W_Root] +ntohl.unwrap_spec = [ObjSpace, r_uint] def htons(space, x): """htons(integer) -> integer @@ -183,24 +178,15 @@ Convert a 16-bit integer from host to network byte order. """ return space.wrap(rsocket.htons(x)) -htons.unwrap_spec = [ObjSpace, int] +htons.unwrap_spec = [ObjSpace, r_uint] -def htonl(space, w_x): +def htonl(space, x): """htonl(integer) -> integer Convert a 32-bit integer from host to network byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.htonl(x)) -htonl.unwrap_spec = [ObjSpace, W_Root] +htonl.unwrap_spec = [ObjSpace, r_uint] def inet_aton(space, ip): """inet_aton(string) -> packed 32-bit IP representation 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 Wed Mar 24 16:01:00 2010 @@ -338,6 +338,7 @@ s.close() def test_NtoH(self): + import sys import _socket as socket # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. @@ -351,7 +352,28 @@ swapped = func(mask) assert swapped & mask == mask try: - func(1L<<34) + func(-1) + except (OverflowError, ValueError): + pass + else: + assert False + try: + func(sys.maxint*2+2) + except OverflowError: + pass + else: + assert False + + def test_NtoH_overflow(self): + skip("we are not checking for overflowing values yet") + import _socket as socket + # Checks that we cannot give too large values to htons etc. + # Skipped for now; CPython 2.6 is also not consistent. + sizes = {socket.htonl: 32, socket.ntohl: 32, + socket.htons: 16, socket.ntohs: 16} + for func, size in sizes.items(): + try: + func(1L << size) except OverflowError: pass else: Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Wed Mar 24 16:01:00 2010 @@ -20,7 +20,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(fd) -open.unwrap_spec = [ObjSpace, str, int, int] +open.unwrap_spec = [ObjSpace, str, "c_int", "c_int"] def lseek(space, fd, pos, how): """Set the current position of a file descriptor. Return the new position. @@ -32,7 +32,7 @@ raise wrap_oserror(space, e) else: return space.wrap(pos) -lseek.unwrap_spec = [ObjSpace, int, r_longlong, int] +lseek.unwrap_spec = [ObjSpace, "c_int", r_longlong, "c_int"] def isatty(space, fd): """Return True if 'fd' is an open file descriptor connected to the @@ -43,7 +43,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -isatty.unwrap_spec = [ObjSpace, int] +isatty.unwrap_spec = [ObjSpace, "c_int"] def read(space, fd, buffersize): """Read data from a file descriptor.""" @@ -53,7 +53,7 @@ raise wrap_oserror(space, e) else: return space.wrap(s) -read.unwrap_spec = [ObjSpace, int, int] +read.unwrap_spec = [ObjSpace, "c_int", int] def write(space, fd, data): """Write a string to a file descriptor. Return the number of bytes @@ -64,7 +64,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -write.unwrap_spec = [ObjSpace, int, 'bufferstr'] +write.unwrap_spec = [ObjSpace, "c_int", 'bufferstr'] def close(space, fd): """Close a file descriptor (for low level IO).""" @@ -72,12 +72,12 @@ os.close(fd) except OSError, e: raise wrap_oserror(space, e) -close.unwrap_spec = [ObjSpace, int] +close.unwrap_spec = [ObjSpace, "c_int"] def closerange(fd_low, fd_high): """Closes all file descriptors in [fd_low, fd_high), ignoring errors.""" rposix.closerange(fd_low, fd_high) -closerange.unwrap_spec = [int, int] +closerange.unwrap_spec = ["c_int", "c_int"] def ftruncate(space, fd, length): """Truncate a file to a specified length.""" @@ -85,21 +85,21 @@ os.ftruncate(fd, length) except OSError, e: raise wrap_oserror(space, e) -ftruncate.unwrap_spec = [ObjSpace, int, r_longlong] +ftruncate.unwrap_spec = [ObjSpace, "c_int", r_longlong] def fsync(space, fd): try: os.fsync(fd) except OSError, e: raise wrap_oserror(space, e) -fsync.unwrap_spec = [ObjSpace, int] +fsync.unwrap_spec = [ObjSpace, "c_int"] def fdatasync(space, fd): try: os.fdatasync(fd) except OSError, e: raise wrap_oserror(space, e) -fdatasync.unwrap_spec = [ObjSpace, int] +fdatasync.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -157,7 +157,7 @@ raise wrap_oserror(space, e) else: return build_stat_result(space, st) -fstat.unwrap_spec = [ObjSpace, int] +fstat.unwrap_spec = [ObjSpace, "c_int"] def stat(space, path): """Perform a stat system call on the given path. Return an object @@ -221,7 +221,7 @@ raise wrap_oserror(space, e) else: return space.wrap(newfd) -dup.unwrap_spec = [ObjSpace, int] +dup.unwrap_spec = [ObjSpace, "c_int"] def dup2(space, old_fd, new_fd): """Duplicate a file descriptor.""" @@ -229,7 +229,7 @@ os.dup2(old_fd, new_fd) except OSError, e: raise wrap_oserror(space, e) -dup2.unwrap_spec = [ObjSpace, int, int] +dup2.unwrap_spec = [ObjSpace, "c_int", "c_int"] def access(space, path, mode): """ @@ -247,7 +247,7 @@ raise wrap_oserror(space, e) else: return space.wrap(ok) -access.unwrap_spec = [ObjSpace, str, int] +access.unwrap_spec = [ObjSpace, str, "c_int"] def times(space): @@ -335,7 +335,7 @@ os.mkdir(path, mode) except OSError, e: raise wrap_oserror(space, e) -mkdir.unwrap_spec = [ObjSpace, str, int] +mkdir.unwrap_spec = [ObjSpace, str, "c_int"] def rmdir(space, path): """Remove a directory.""" @@ -353,7 +353,7 @@ raise OperationError(space.w_ValueError, space.wrap("strerror() argument out of range")) return space.wrap(text) -strerror.unwrap_spec = [ObjSpace, int] +strerror.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -440,7 +440,7 @@ os.chmod(path, mode) except OSError, e: raise wrap_oserror(space, e) -chmod.unwrap_spec = [ObjSpace, str, int] +chmod.unwrap_spec = [ObjSpace, str, "c_int"] def rename(space, old, new): "Rename a file or directory." @@ -454,7 +454,7 @@ "Set the current numeric umask and return the previous umask." prevmask = os.umask(mask) return space.wrap(prevmask) -umask.unwrap_spec = [ObjSpace, int] +umask.unwrap_spec = [ObjSpace, "c_int"] def getpid(space): "Return the current process id." @@ -471,7 +471,7 @@ os.kill(pid, sig) except OSError, e: raise wrap_oserror(space, e) -kill.unwrap_spec = [ObjSpace, int, int] +kill.unwrap_spec = [ObjSpace, "c_int", "c_int"] def abort(space): """Abort the interpreter immediately. This 'dumps core' or otherwise fails @@ -531,11 +531,11 @@ except OSError, e: raise wrap_oserror(space, e) return space.newtuple([space.wrap(pid), space.wrap(status)]) -waitpid.unwrap_spec = [ObjSpace, int, int] +waitpid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def _exit(space, status): os._exit(status) -_exit.unwrap_spec = [ObjSpace, int] +_exit.unwrap_spec = [ObjSpace, "c_int"] def execv(space, command, w_args): """ execv(path, args) @@ -649,7 +649,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setuid.unwrap_spec = [ObjSpace, int] +setuid.unwrap_spec = [ObjSpace, "c_uint"] def seteuid(space, arg): """ seteuid(uid) @@ -661,7 +661,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -seteuid.unwrap_spec = [ObjSpace, int] +seteuid.unwrap_spec = [ObjSpace, "c_uint"] def setgid(space, arg): """ setgid(gid) @@ -673,7 +673,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setgid.unwrap_spec = [ObjSpace, int] +setgid.unwrap_spec = [ObjSpace, "c_uint"] def setegid(space, arg): """ setegid(gid) @@ -685,7 +685,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setegid.unwrap_spec = [ObjSpace, int] +setegid.unwrap_spec = [ObjSpace, "c_uint"] def chroot(space, path): """ chroot(path) @@ -761,7 +761,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(pgid) -getpgid.unwrap_spec = [ObjSpace, int] +getpgid.unwrap_spec = [ObjSpace, "c_int"] def setpgid(space, pid, pgrp): """ setpgid(pid, pgrp) @@ -773,7 +773,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setpgid.unwrap_spec = [ObjSpace, int, int] +setpgid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def setreuid(space, ruid, euid): """ setreuid(ruid, euid) @@ -785,7 +785,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setreuid.unwrap_spec = [ObjSpace, int, int] +setreuid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] def setregid(space, rgid, egid): """ setregid(rgid, egid) @@ -797,7 +797,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setregid.unwrap_spec = [ObjSpace, int, int] +setregid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] def getsid(space, pid): """ getsid(pid) -> sid @@ -809,7 +809,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(sid) -getsid.unwrap_spec = [ObjSpace, int] +getsid.unwrap_spec = [ObjSpace, "c_int"] def setsid(space): """ setsid() @@ -831,7 +831,7 @@ def WSTAR(space, status): return space.newbool(getattr(os, name)(status)) WSTAR.__doc__ = getattr(os, name).__doc__ - WSTAR.unwrap_spec = [ObjSpace, int] + WSTAR.unwrap_spec = [ObjSpace, "c_int"] WSTAR.func_name = name return WSTAR @@ -845,7 +845,7 @@ return space.wrap(os.ttyname(fd)) except OSError, e: raise wrap_oserror(space, e) -ttyname.unwrap_spec = [ObjSpace, int] +ttyname.unwrap_spec = [ObjSpace, "c_int"] def sysconf(space, w_num_or_name): # XXX slightly non-nice, reuses the sysconf of the underlying os module @@ -866,7 +866,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -chown.unwrap_spec = [ObjSpace, str, int, int] +chown.unwrap_spec = [ObjSpace, str, "c_uint", "c_uint"] if _WIN: from pypy.rlib import rwin32 Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Wed Mar 24 16:01:00 2010 @@ -380,7 +380,7 @@ if hasattr(os, 'setuid'): def test_os_setuid_error(self): os = self.posix - raises(OSError, os.setuid, -100000) + raises((OSError, ValueError, OverflowError), os.setuid, -100000) if hasattr(os, 'getgid'): def test_os_getgid(self): @@ -396,13 +396,13 @@ if hasattr(os, 'setgid'): def test_os_setgid_error(self): os = self.posix - raises(OSError, os.setgid, -100000) + raises((OSError, ValueError, OverflowError), os.setgid, -100000) if hasattr(os, 'getsid'): def test_os_getsid(self): os = self.posix assert os.getsid(0) == self.getsid0 - raises(OSError, os.getsid, -100000) + raises((OSError, ValueError, OverflowError), os.getsid, -100000) if hasattr(os, 'sysconf'): def test_os_sysconf(self): Modified: pypy/trunk/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/floatobject.py Wed Mar 24 16:01:00 2010 @@ -1,9 +1,11 @@ +import operator, new from pypy.objspace.std.objspace import * from pypy.interpreter import gateway from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT +from pypy.rlib.rbigint import rbigint import math from pypy.objspace.std.intobject import W_IntObject @@ -88,82 +90,115 @@ s = formatd("%.12g", x) return space.wrap(should_not_look_like_an_int(s)) +# ____________________________________________________________ +# A mess to handle all cases of float comparison without relying +# on delegation, which can unfortunately loose precision when +# casting an int or a long to a float. + +def list_compare_funcs(declarator): + for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: + func, name = declarator(op) + globals()[name] = func_with_new_name(func, name) + +def _reverse(opname): + if opname[0] == 'l': return 'g' + opname[1:] + elif opname[0] == 'g': return 'l' + opname[1:] + else: return opname -def declare_new_float_comparison(opname): - import operator - from pypy.tool.sourcetools import func_with_new_name - op = getattr(operator, opname) - def f(space, w_int1, w_int2): - i = w_int1.floatval - j = w_int2.floatval - return space.newbool(op(i, j)) - name = opname + "__Float_Float" - return func_with_new_name(f, name), name - -for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: - func, name = declare_new_float_comparison(op) - globals()[name] = func - -# for overflowing comparisons between longs and floats -# XXX we might have to worry (later) about eq__Float_Int, for the case -# where int->float conversion may lose precision :-( -def eq__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x) or math.floor(x) != x: - return space.w_False - try: - w_long1 = W_LongObject.fromfloat(x) - except OverflowError: - return space.w_False - return space.eq(w_long1, w_long2) - -def eq__Long_Float(space, w_long1, w_float2): - return eq__Float_Long(space, w_float2, w_long1) - -def ne__Float_Long(space, w_float1, w_long2): - return space.not_(eq__Float_Long(space, w_float1, w_long2)) - -def ne__Long_Float(space, w_long1, w_float2): - return space.not_(eq__Float_Long(space, w_float2, w_long1)) - -def lt__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x): - return space.newbool(x < 0.0) - x_floor = math.floor(x) - try: - w_long1 = W_LongObject.fromfloat(x_floor) - except OverflowError: - return space.newbool(x < 0.0) - return space.lt(w_long1, w_long2) - -def lt__Long_Float(space, w_long1, w_float2): - return space.not_(le__Float_Long(space, w_float2, w_long1)) -def le__Float_Long(space, w_float1, w_long2): - # XXX it's naive anyway - if space.is_true(space.lt(w_float1, w_long2)): - return space.w_True +def declare_compare_bigint(opname): + """Return a helper function that implements a float-bigint comparison.""" + op = getattr(operator, opname) + # + if opname == 'eq' or opname == 'ne': + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1) or math.floor(f1) != f1: + return opname == 'ne' + b1 = rbigint.fromfloat(f1) + res = b1.eq(b2) + if opname == 'ne': + res = not res + return res else: - return space.eq(w_float1, w_long2) + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1): + return op(f1, 0.0) + if opname == 'gt' or opname == 'le': + # 'float > long' <==> 'ceil(float) > long' + # 'float <= long' <==> 'ceil(float) <= long' + f1 = math.ceil(f1) + else: + # 'float < long' <==> 'floor(float) < long' + # 'float >= long' <==> 'floor(float) >= long' + f1 = math.floor(f1) + b1 = rbigint.fromfloat(f1) + return getattr(b1, opname)(b2) + # + return do_compare_bigint, 'compare_bigint_' + opname +list_compare_funcs(declare_compare_bigint) -def le__Long_Float(space, w_long1, w_float2): - return space.not_(lt__Float_Long(space, w_float2, w_long1)) -def gt__Float_Long(space, w_float1, w_long2): - return space.not_(le__Float_Long(space, w_float1, w_long2)) +def declare_cmp_float_float(opname): + op = getattr(operator, opname) + def f(space, w_float1, w_float2): + f1 = w_float1.floatval + f2 = w_float2.floatval + return space.newbool(op(f1, f2)) + return f, opname + "__Float_Float" +list_compare_funcs(declare_cmp_float_float) -def gt__Long_Float(space, w_long1, w_float2): - return lt__Float_Long(space, w_float2, w_long1) +def declare_cmp_float_int(opname): + op = getattr(operator, opname) + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_int2): + f1 = w_float1.floatval + i2 = w_int2.intval + f2 = float(i2) + if LONG_BIT > 32 and int(f2) != i2: + res = compare(f1, rbigint.fromint(i2)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Float_Int" +list_compare_funcs(declare_cmp_float_int) + +def declare_cmp_float_long(opname): + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_long2): + f1 = w_float1.floatval + b2 = w_long2.num + return space.newbool(compare(f1, b2)) + return f, opname + "__Float_Long" +list_compare_funcs(declare_cmp_float_long) -def ge__Float_Long(space, w_float1, w_long2): - return space.not_(lt__Float_Long(space, w_float1, w_long2)) +def declare_cmp_int_float(opname): + op = getattr(operator, opname) + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_int1, w_float2): + f2 = w_float2.floatval + i1 = w_int1.intval + f1 = float(i1) + if LONG_BIT > 32 and int(f1) != i1: + res = revcompare(f2, rbigint.fromint(i1)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Int_Float" +list_compare_funcs(declare_cmp_int_float) + +def declare_cmp_long_float(opname): + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_long1, w_float2): + f2 = w_float2.floatval + b1 = w_long1.num + return space.newbool(revcompare(f2, b1)) + return f, opname + "__Long_Float" +list_compare_funcs(declare_cmp_long_float) -def ge__Long_Float(space, w_long1, w_float2): - return le__Float_Long(space, w_float2, w_long1) +# ____________________________________________________________ def hash__Float(space, w_value): return space.wrap(_hash_float(space, w_value.floatval)) Modified: pypy/trunk/pypy/objspace/std/longobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/longobject.py (original) +++ pypy/trunk/pypy/objspace/std/longobject.py Wed Mar 24 16:01:00 2010 @@ -120,11 +120,46 @@ def str__Long(space, w_long): return space.wrap(w_long.num.str()) -def eq__Long_Long(space, w_long1, w_long2): - return space.newbool(w_long1.num.eq(w_long2.num)) def lt__Long_Long(space, w_long1, w_long2): return space.newbool(w_long1.num.lt(w_long2.num)) +def le__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.le(w_long2.num)) +def eq__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.eq(w_long2.num)) +def ne__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ne(w_long2.num)) +def gt__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.gt(w_long2.num)) +def ge__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ge(w_long2.num)) + +def lt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.lt(rbigint.fromint(w_int2.intval))) +def le__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.le(rbigint.fromint(w_int2.intval))) +def eq__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.eq(rbigint.fromint(w_int2.intval))) +def ne__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ne(rbigint.fromint(w_int2.intval))) +def gt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.gt(rbigint.fromint(w_int2.intval))) +def ge__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ge(rbigint.fromint(w_int2.intval))) + +def lt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).lt(w_long2.num)) +def le__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).le(w_long2.num)) +def eq__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).eq(w_long2.num)) +def ne__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ne(w_long2.num)) +def gt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).gt(w_long2.num)) +def ge__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ge(w_long2.num)) + def hash__Long(space, w_value): return space.wrap(w_value.num.hash()) Modified: pypy/trunk/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_floatobject.py Wed Mar 24 16:01:00 2010 @@ -212,6 +212,8 @@ assert 13 <= 13.01 def test_comparison_more(self): + import sys + is_pypy = '__pypy__' in sys.builtin_module_names infinity = 1e200*1e200 nan = infinity/infinity for x in (123, 1 << 30, @@ -239,12 +241,27 @@ assert ((x + 1) > float(x)) assert not ((x + 1) < float(x)) # - #assert not (x == nan) - #assert not (x >= nan) - #assert not (x <= nan) - #assert (x != nan) - #assert not (x > nan) - #assert not (x < nan) + assert not (x == infinity) + assert not (x >= infinity) + assert (x <= infinity) + assert (x != infinity) + assert not (x > infinity) + assert (x < infinity) + # + assert not (x == -infinity) + assert (x >= -infinity) + assert not (x <= -infinity) + assert (x != -infinity) + assert (x > -infinity) + assert not (x < -infinity) + # + if is_pypy: + assert not (x == nan) + assert not (x >= nan) + assert not (x <= nan) + assert (x != nan) + assert not (x > nan) + assert not (x < nan) # assert (float(x) == x) assert (float(x) <= x) @@ -267,19 +284,35 @@ assert (float(x) < (x + 1)) assert not (float(x) > (x + 1)) # - #assert not (nan == x) - #assert not (nan <= x) - #assert not (nan >= x) - #assert (nan != x) - #assert not (nan < x) - #assert not (nan > x) + assert not (infinity == x) + assert (infinity >= x) + assert not (infinity <= x) + assert (infinity != x) + assert (infinity > x) + assert not (infinity < x) + # + assert not (-infinity == x) + assert not (-infinity >= x) + assert (-infinity <= x) + assert (-infinity != x) + assert not (-infinity > x) + assert (-infinity < x) + # + if is_pypy: + assert not (nan == x) + assert not (nan <= x) + assert not (nan >= x) + assert (nan != x) + assert not (nan < x) + assert not (nan > x) def test_multimethod_slice(self): assert 5 .__add__(3.14) is NotImplemented assert 3.25 .__add__(5) == 8.25 - if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent - assert 5 .__eq__(3.14) is NotImplemented - assert 3.14 .__eq__(5) is False + # xxx we are also a bit inconsistent about the following + #if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent + # assert 5 .__eq__(3.14) is NotImplemented + # assert 3.14 .__eq__(5) is False #if hasattr(long, '__eq__'): # for py.test -A: CPython is inconsistent # assert 5L .__eq__(3.14) is NotImplemented # assert 3.14 .__eq__(5L) is False Modified: pypy/trunk/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_longobject.py Wed Mar 24 16:01:00 2010 @@ -60,37 +60,79 @@ assert a == 3L def test_compare(self): - BIG = 1L << 9999 - assert 0 == 0L - assert not (0 != 0L) - assert 0L == 0 - assert not (0L != 0) - assert not (0 == BIG) - assert 0 != BIG - assert not (BIG == 0) - assert BIG != 0 - assert not (0L == BIG) - assert 0L != BIG - assert 0 <= 0L - assert not (0 < 0L) - assert 0 <= BIG - assert 0 < BIG - assert not (BIG <= 0) - assert not (BIG < 0) - assert 0L <= 0L - assert not (0L < 0L) - assert 0L <= BIG - assert 0L < BIG - assert not (BIG <= 0L) - assert not (BIG < 0L) - assert not (0 <= -BIG) - assert not (0 < -BIG) - assert -BIG <= 0 - assert -BIG < 0 - assert not (0L <= -BIG) - assert not (0L < -BIG) - assert -BIG <= 0L - assert -BIG < 0L + for BIG in (1L, 1L << 62, 1L << 9999): + assert 0 == 0L + assert not (0 != 0L) + assert 0L == 0 + assert not (0L != 0) + assert not (0 == BIG) + assert 0 != BIG + assert not (BIG == 0) + assert BIG != 0 + assert not (0L == BIG) + assert 0L != BIG + assert 0 <= 0L + assert not (0 < 0L) + assert 0 <= BIG + assert 0 < BIG + assert not (BIG <= 0) + assert not (BIG < 0) + assert 0L <= 0L + assert not (0L < 0L) + assert 0L <= BIG + assert 0L < BIG + assert not (BIG <= 0L) + assert not (BIG < 0L) + assert not (0 <= -BIG) + assert not (0 < -BIG) + assert -BIG <= 0 + assert -BIG < 0 + assert not (0L <= -BIG) + assert not (0L < -BIG) + assert -BIG <= 0L + assert -BIG < 0L + # + assert not (BIG < int(BIG)) + assert (BIG <= int(BIG)) + assert (BIG == int(BIG)) + assert not (BIG != int(BIG)) + assert not (BIG > int(BIG)) + assert (BIG >= int(BIG)) + # + assert (BIG < int(BIG)+1) + assert (BIG <= int(BIG)+1) + assert not (BIG == int(BIG)+1) + assert (BIG != int(BIG)+1) + assert not (BIG > int(BIG)+1) + assert not (BIG >= int(BIG)+1) + # + assert not (BIG < int(BIG)-1) + assert not (BIG <= int(BIG)-1) + assert not (BIG == int(BIG)-1) + assert (BIG != int(BIG)-1) + assert (BIG > int(BIG)-1) + assert (BIG >= int(BIG)-1) + # + assert not (int(BIG) < BIG) + assert (int(BIG) <= BIG) + assert (int(BIG) == BIG) + assert not (int(BIG) != BIG) + assert not (int(BIG) > BIG) + assert (int(BIG) >= BIG) + # + assert not (int(BIG)+1 < BIG) + assert not (int(BIG)+1 <= BIG) + assert not (int(BIG)+1 == BIG) + assert (int(BIG)+1 != BIG) + assert (int(BIG)+1 > BIG) + assert (int(BIG)+1 >= BIG) + # + assert (int(BIG)-1 < BIG) + assert (int(BIG)-1 <= BIG) + assert not (int(BIG)-1 == BIG) + assert (int(BIG)-1 != BIG) + assert not (int(BIG)-1 > BIG) + assert not (int(BIG)-1 >= BIG) def test_conversion(self): class long2(long): Modified: pypy/trunk/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/trunk/pypy/rlib/rarithmetic.py (original) +++ pypy/trunk/pypy/rlib/rarithmetic.py Wed Mar 24 16:01:00 2010 @@ -307,7 +307,7 @@ if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) if val < 0: - val = - ((-val) & klass.MASK) + val = ~ ((~val) & klass.MASK) return super(signed_int, klass).__new__(klass, val) typemap = {} Modified: pypy/trunk/pypy/rlib/rbigint.py ============================================================================== --- pypy/trunk/pypy/rlib/rbigint.py (original) +++ pypy/trunk/pypy/rlib/rbigint.py Wed Mar 24 16:01:00 2010 @@ -49,6 +49,7 @@ class rbigint(object): """This is a reimplementation of longs using a list of digits.""" + # XXX relace the list of ints with a list of rffi.INTs, maybe def __init__(self, digits=None, sign=0): if digits is None or len(digits) == 0: @@ -272,13 +273,13 @@ return False def le(self, other): - return self.lt(other) or self.eq(other) + return not other.lt(self) def gt(self, other): - return other.le(self) + return other.lt(self) def ge(self, other): - return other.lt(self) + return not self.lt(other) def hash(self): return _hash(self) Modified: pypy/trunk/pypy/rlib/rmarshal.py ============================================================================== --- pypy/trunk/pypy/rlib/rmarshal.py (original) +++ pypy/trunk/pypy/rlib/rmarshal.py Wed Mar 24 16:01:00 2010 @@ -6,7 +6,7 @@ from pypy.annotation.signature import annotation from pypy.annotation.listdef import ListDef, TooLateForChange from pypy.tool.pairtype import pair, pairtype -from pypy.rlib.rarithmetic import formatd, r_longlong, intmask +from pypy.rlib.rarithmetic import formatd, r_longlong, intmask, LONG_BIT from pypy.rlib.rarithmetic import break_up_float, parts_to_float from pypy.rlib.unroll import unrolling_iterable @@ -151,8 +151,12 @@ add_loader(annmodel.s_Bool, load_bool) def dump_int(buf, x): - buf.append(TYPE_INT) - w_long(buf, x) + # only use TYPE_INT on 32-bit platforms + if LONG_BIT > 32: + dump_longlong(buf, r_longlong(x)) + else: + buf.append(TYPE_INT) + w_long(buf, x) add_dumper(annmodel.SomeInteger(), dump_int) def load_int_nonneg(loader): @@ -163,9 +167,14 @@ add_loader(annmodel.SomeInteger(nonneg=True), load_int_nonneg) def load_int(loader): - if readchr(loader) != TYPE_INT: - raise ValueError("expected an int") - return readlong(loader) + r = readchr(loader) + if LONG_BIT > 32 and r == TYPE_INT64: + x = readlong(loader) & 0xFFFFFFFF + x |= readlong(loader) << 32 + return x + if r == TYPE_INT: + return readlong(loader) + raise ValueError("expected an int") add_loader(annmodel.SomeInteger(), load_int) def dump_longlong(buf, x): Modified: pypy/trunk/pypy/rlib/rstack.py ============================================================================== --- pypy/trunk/pypy/rlib/rstack.py (original) +++ pypy/trunk/pypy/rlib/rstack.py Wed Mar 24 16:01:00 2010 @@ -38,8 +38,9 @@ stack_too_big = rffi.llexternal('LL_stack_too_big', [], rffi.INT, compilation_info=compilation_info, _nowrapper=True, - _callable=lambda: 0, + _callable=lambda: _zero, sandboxsafe=True) +_zero = rffi.cast(rffi.INT, 0) def stack_check(): if rffi.cast(lltype.Signed, stack_too_big()): Modified: pypy/trunk/pypy/rlib/test/test_rarithmetic.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rarithmetic.py (original) +++ pypy/trunk/pypy/rlib/test/test_rarithmetic.py Wed Mar 24 16:01:00 2010 @@ -197,6 +197,10 @@ x = intmask(tp(5)) assert (type(x), x) == (int, 5) +def test_bug_creating_r_int(): + minint = -sys.maxint-1 + assert r_int(r_int(minint)) == minint + def test_ovfcheck(): one = 1 x = sys.maxint Modified: pypy/trunk/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rbigint.py (original) +++ pypy/trunk/pypy/rlib/test/test_rbigint.py Wed Mar 24 16:01:00 2010 @@ -106,7 +106,7 @@ assert rbigint.fromrarith_int(r_uint(17)).eq(rbigint([17], 1)) assert rbigint.fromrarith_int(r_uint(BASE-1)).eq(rbigint([intmask(BASE-1)], 1)) assert rbigint.fromrarith_int(r_uint(BASE)).eq(rbigint([0, 1], 1)) - assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) + #assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) assert rbigint.fromrarith_int(r_uint(sys.maxint)).eq( rbigint.fromint(sys.maxint)) assert rbigint.fromrarith_int(r_uint(sys.maxint+1)).eq( @@ -193,6 +193,14 @@ f2 = rbigint.fromlong(y) assert (x < y) == f1.lt(f2) + def test_order(self): + f6 = rbigint.fromint(6) + f7 = rbigint.fromint(7) + assert (f6.lt(f6), f6.lt(f7), f7.lt(f6)) == (0,1,0) + assert (f6.le(f6), f6.le(f7), f7.le(f6)) == (1,1,0) + assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1) + assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1) + def test_int_conversion(self): f1 = rbigint.fromlong(12332) f2 = rbigint.fromint(12332) @@ -465,9 +473,12 @@ def test_args_from_rarith_int(self): from pypy.rpython.tool.rfficache import platform + from pypy.rlib.rarithmetic import r_int classlist = platform.numbertype_to_rclass.values() fnlist = [] for r in classlist: + if r is r_int: # and also r_longlong on 64-bit + continue if r is int: mask = sys.maxint*2+1 signed = True Modified: pypy/trunk/pypy/rlib/test/test_rmarshal.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rmarshal.py (original) +++ pypy/trunk/pypy/rlib/test/test_rmarshal.py Wed Mar 24 16:01:00 2010 @@ -2,7 +2,7 @@ import marshal from pypy.rlib.rmarshal import * from pypy.annotation import model as annmodel -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT types_that_can_be_none = [ [int], @@ -17,6 +17,10 @@ assert marshal.loads(''.join(buf)) == 5 buf = [] + get_marshaller(int)(buf, -555) + assert marshal.loads(''.join(buf)) == -555 + + buf = [] get_marshaller(float)(buf, 3.25) assert marshal.loads(''.join(buf)) == 3.25 @@ -37,6 +41,15 @@ assert marshal.loads(''.join(buf)) == 0x12380000007 buf = [] + get_marshaller(r_longlong)(buf, r_longlong(-0x12380000007)) + assert marshal.loads(''.join(buf)) == -0x12380000007 + + if LONG_BIT > 32: + buf = [] + get_marshaller(int)(buf, -0x12340000007) + assert marshal.loads(''.join(buf)) == -0x12340000007 + + buf = [] get_marshaller([int])(buf, [2, 5, -7]) assert marshal.loads(''.join(buf)) == [2, 5, -7] @@ -54,6 +67,9 @@ buf = 'i\x05\x00\x00\x00' assert get_unmarshaller(int)(buf) == 5 + buf = 'i\x00\xf0\xff\xff' + assert get_unmarshaller(int)(buf) == -4096 + buf = 'f\x043.25' assert get_unmarshaller(float)(buf) == 3.25 @@ -75,6 +91,16 @@ buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' assert get_unmarshaller(r_longlong)(buf) == 0x12380000007 + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(r_longlong)(buf) == -7566046822028738560L + + if LONG_BIT > 32: + buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' + assert get_unmarshaller(int)(buf) == 0x12380000007 + + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(int)(buf) == -7566046822028738560 + buf = ('[\x03\x00\x00\x00i\x02\x00\x00\x00i\x05\x00\x00\x00' 'i\xf9\xff\xff\xff') assert get_unmarshaller([int])(buf) == [2, 5, -7] @@ -98,10 +124,18 @@ return ''.join(buf) res = interpret(f, []) res = ''.join(res.chars) - assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' - 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' - 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' - 'f\x061e+100') + if LONG_BIT == 32: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' + 'f\x061e+100') + else: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00' + 'I\x05\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'I\x07\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00world' + 'f\x061e+100') def test_llinterp_unmarshal(): from pypy.rpython.test.test_llinterp import interpret Modified: pypy/trunk/pypy/rlib/test/test_rstruct.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rstruct.py (original) +++ pypy/trunk/pypy/rlib/test/test_rstruct.py Wed Mar 24 16:01:00 2010 @@ -1,12 +1,14 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.rstruct.runpack import runpack +from pypy.rlib.rarithmetic import LONG_BIT import struct class BaseTestRStruct(BaseRtypingTest): def test_unpack(self): + pad = '\x00' * (LONG_BIT//8-1) # 3 or 7 null bytes def fn(): - return runpack('sll', 'a\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00')[1] + return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1] assert fn() == 3 assert self.interpret(fn, []) == 3 Modified: pypy/trunk/pypy/rpython/lltypesystem/llgroup.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/llgroup.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/llgroup.py Wed Mar 24 16:01:00 2010 @@ -50,9 +50,11 @@ if LONG_BIT == 32: + HALFSHIFT = 16 HALFWORD = rffi.USHORT r_halfword = rffi.r_ushort else: + HALFSHIFT = 32 HALFWORD = rffi.UINT r_halfword = rffi.r_uint @@ -97,7 +99,7 @@ '&~0xFFFF' or with a direct masking like '&0x10000' (resp. on 64-bit platform, with '&~0xFFFFFFFF' or '&0x100000000'). """ - MASK = (1<<(LONG_BIT//2))-1 # 0xFFFF or 0xFFFFFFFF + MASK = (1<membername) / 4)) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ @@ -22,33 +22,31 @@ /* A macro to crash at compile-time if sizeof(group) is too large. Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - { typedef char group_##groupname##_is_too_large[ \ - 2*(sizeof(groupname) <= 65536*4)-1]; } +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 65536*4)-1]; #else /******************************************************/ /* On 64-bit platforms, a CombinedSymbolic is two UINTs, and the lower - one stores a real pointer to the group memeber. The limitation is - that this pointer must fit inside 32-bit, i.e. the whole group must - be located in the first 32 bits of address space. */ + one is an 32-bit offset from the start of the group. */ typedef unsigned int pypy_halfword_t; -#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ - ((long)(&groupname.membername)) +#define GROUP_MEMBER_OFFSET(grouptype, membername) \ + offsetof(grouptype, membername) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ - ((long)compactoffset) + (((char*)groupptr) + (long)compactoffset) #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ - ((long)compactoffset + skipoffset) + (((char*)groupptr) + skipoffset + (long)compactoffset) -/* A macro to check at run-time if the group is below the 32-bit limit. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - if ((unsigned long)(&groupname.lastname) > 0xFFFFFFFF) \ - error = "group " #groupname " is not located in the " \ - "initial 32 bits of address space" +/* A macro to crash at compile-time if sizeof(group) is too large. + Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 4294967296L)-1]; #endif /*****************************************************/ Modified: pypy/trunk/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/trunk/pypy/translator/c/test/test_lltyped.py Wed Mar 24 16:01:00 2010 @@ -732,14 +732,17 @@ ('z4', Signed), ('u4', Signed)) goffsets = [] for i in range(4096 + toobig): - goffsets.append(grp.add_member(malloc(S1, immortal=True))) + ofs = grp.add_member(malloc(S1, immortal=True)) + goffsets.append(llgroup.CombinedSymbolic(ofs, 0)) grpptr = grp._as_ptr() def f(n): - p = llop.get_group_member(Ptr(S1), grpptr, goffsets[n]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[n]) + p = llop.get_group_member(Ptr(S1), grpptr, o) p.x = 5 for i in range(len(goffsets)): if i != n: - q = llop.get_group_member(Ptr(S1), grpptr, goffsets[i]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[i]) + q = llop.get_group_member(Ptr(S1), grpptr, o) q.x = 666 return p.x if toobig: From arigo at codespeak.net Wed Mar 24 16:01:19 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 16:01:19 +0100 (CET) Subject: [pypy-svn] r72722 - pypy/branch/fix-64 Message-ID: <20100324150119.4F601282BDD@codespeak.net> Author: arigo Date: Wed Mar 24 16:01:17 2010 New Revision: 72722 Removed: pypy/branch/fix-64/ Log: Remove merged branch. From arigo at codespeak.net Wed Mar 24 16:01:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 16:01:53 +0100 (CET) Subject: [pypy-svn] r72723 - pypy/branch/fix-64 Message-ID: <20100324150153.2BC14282BDD@codespeak.net> Author: arigo Date: Wed Mar 24 16:01:51 2010 New Revision: 72723 Added: pypy/branch/fix-64/ - copied from r72722, pypy/trunk/ Log: Recreate a branch for the 2nd round of fixing. From afa at codespeak.net Wed Mar 24 16:09:20 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 16:09:20 +0100 (CET) Subject: [pypy-svn] r72725 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100324150920.887B0282BDC@codespeak.net> Author: afa Date: Wed Mar 24 16:09:18 2010 New Revision: 72725 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: Add support for Py_InitModule4: module docstring and "cookie" object passed to every function of the module. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 16:09:18 2010 @@ -226,7 +226,10 @@ arg = args[i] if (typ is PyObject and callable.api_func.argnames[i].startswith('w_')): - arg = from_ref(space, arg) + if arg: + arg = from_ref(space, arg) + else: + arg = None boxed_args.append(arg) state = space.fromcache(State) try: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h Wed Mar 24 16:09:18 2010 @@ -7,7 +7,21 @@ extern "C" { #endif -PyObject *Py_InitModule(const char* name, PyMethodDef* methods); +#define PYTHON_API_VERSION 1013 +#define PYTHON_API_STRING "1013" + +PyObject *Py_InitModule4(const char* name, PyMethodDef* methods, + const char *doc, PyObject *self, + int apiver); + +#define Py_InitModule(name, methods) \ + Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \ + PYTHON_API_VERSION) + +#define Py_InitModule3(name, methods, doc) \ + Py_InitModule4(name, methods, doc, (PyObject *)NULL, \ + PYTHON_API_VERSION) + PyObject * PyModule_GetDict(PyObject *); Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 24 16:09:18 2010 @@ -22,18 +22,22 @@ space.setitem(w_modules, w_name, w_mod) return w_mod - at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], PyObject, borrowed=True) -def Py_InitModule(space, name, methods): + at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef), rffi.CCHARP, + PyObject, rffi.INT_real], PyObject, borrowed=True) +def Py_InitModule4(space, name, methods, doc, w_self, apiver): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) dict_w = {} - convert_method_defs(space, dict_w, methods, None) + convert_method_defs(space, dict_w, methods, None, w_self) for key, w_value in dict_w.items(): space.setattr(w_mod, space.wrap(key), w_value) + if doc: + space.setattr(w_mod, space.wrap("__doc__"), + space.wrap(rffi.charp2str(doc))) return w_mod -def convert_method_defs(space, dict_w, methods, pto): +def convert_method_defs(space, dict_w, methods, pto, w_self=None): methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods) if methods: i = -1 @@ -48,7 +52,7 @@ if flags & METH_CLASS or flags & METH_STATIC: raise OperationError(space.w_ValueError, "module functions cannot set METH_CLASS or METH_STATIC") - w_obj = PyCFunction_NewEx(space, method, None) + w_obj = PyCFunction_NewEx(space, method, w_self) else: if methodname in dict_w and not (flags & METH_COEXIST): continue Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 24 16:09:18 2010 @@ -23,9 +23,8 @@ class TestApi: def test_signature(self): - assert 'Py_InitModule' in api.FUNCTIONS - assert api.FUNCTIONS['Py_InitModule'].argtypes == [ - rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])] + assert 'PyModule_Check' in api.FUNCTIONS + assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject] def test_padding(self): T = api.get_padded_type(api.PyObject.TO, 42) @@ -173,6 +172,33 @@ assert module.return_pi is not None assert module.return_pi() == 3.14 + def test_InitModule4(self): + init = """ + PyObject *cookie = PyFloat_FromDouble(3.14); + Py_InitModule4("foo", methods, "docstring", + cookie, PYTHON_API_VERSION); + Py_DECREF(cookie); + """ + body = """ + PyObject* return_cookie(PyObject* self, PyObject *args) + { + if (self) + { + Py_INCREF(self); + return self; + } + else + Py_RETURN_FALSE; + } + static PyMethodDef methods[] = { + { "return_cookie", return_cookie, METH_NOARGS }, + { NULL } + }; + """ + module = self.import_module(name='foo', init=init, body=body) + assert module.__doc__ == "docstring" + assert module.return_cookie() == 3.14 + def test_export_function2(self): import sys init = """ From arigo at codespeak.net Wed Mar 24 17:47:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 17:47:37 +0100 (CET) Subject: [pypy-svn] r72732 - pypy/branch/fix-64/pypy/translator/c Message-ID: <20100324164737.58447282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 17:47:34 2010 New Revision: 72732 Modified: pypy/branch/fix-64/pypy/translator/c/node.py Log: Whack at node.py until the line '((%s)(void*)%s)' no longer appears. This was an improper cast and causes recent gcc's to produce bogus code. Modified: pypy/branch/fix-64/pypy/translator/c/node.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/node.py (original) +++ pypy/branch/fix-64/pypy/translator/c/node.py Wed Mar 24 17:47:34 2010 @@ -37,6 +37,8 @@ class StructDefNode: typetag = 'struct' + extra_union_for_varlength = True + def __init__(self, db, STRUCT, varlength=1): self.db = db self.STRUCT = STRUCT @@ -82,7 +84,8 @@ self.fields = [] db = self.db STRUCT = self.STRUCT - varlength = self.varlength + if self.varlength != 1: + self.normalizedtypename = db.gettype(STRUCT, who_asks=self) if needs_gcheader(self.STRUCT): for fname, T in db.gcpolicy.struct_gcheader_definition(self): self.fields.append((fname, db.gettype(T, who_asks=self))) @@ -151,6 +154,12 @@ if is_empty: yield '\t' + 'char _dummy; /* this struct is empty */' yield '};' + if self.varlength != 1: + assert self.typetag == 'struct' + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_field): for name in self.fieldnames: @@ -162,6 +171,7 @@ def debug_offsets(self): # generate number exprs giving the offset of the elements in the struct + assert self.varlength == 1 for name in self.fieldnames: FIELD_T = self.c_struct_field_type(name) if FIELD_T is Void: @@ -178,15 +188,15 @@ class ArrayDefNode: typetag = 'struct' + extra_union_for_varlength = True def __init__(self, db, ARRAY, varlength=1): self.db = db self.ARRAY = ARRAY self.LLTYPE = ARRAY - original_varlength = varlength self.gcfields = [] self.varlength = varlength - if original_varlength == 1: + if varlength == 1: basename = 'array' with_number = True else: @@ -204,6 +214,8 @@ db = self.db ARRAY = self.ARRAY self.gcinfo # force it to be computed + if self.varlength != 1: + self.normalizedtypename = db.gettype(ARRAY, who_asks=self) if needs_gcheader(ARRAY): for fname, T in db.gcpolicy.array_gcheader_definition(self): self.gcfields.append((fname, db.gettype(T, who_asks=self))) @@ -251,8 +263,14 @@ line = 'char _dummy; ' + line yield '\t' + line yield '};' + if self.varlength != 1: + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_item): + assert self.varlength == 1 ARRAY = self.ARRAY # we need a unique name for this C variable, or at least one that does # not collide with the expression in 'prefix' @@ -279,6 +297,7 @@ def debug_offsets(self): # generate three offsets for debugging inspection + assert self.varlength == 1 if not self.ARRAY._hints.get('nolength', False): yield 'offsetof(struct %s, length)' % (self.name,) else: @@ -299,6 +318,7 @@ gcinfo = None name = None forward_decl = None + extra_union_for_varlength = False def __init__(self, db, ARRAY, varlength=1): self.db = db @@ -349,6 +369,7 @@ gcinfo = None name = None typetag = 'struct' + extra_union_for_varlength = False def __init__(self, db, FIXEDARRAY): self.db = db @@ -461,28 +482,42 @@ parentnode = db.getcontainernode(parent) defnode = db.gettypedefnode(parentnode.T) self.name = defnode.access_expr(parentnode.name, parentindex) - self.ptrname = '(&%s)' % self.name if self.typename != self.implementationtypename: - ptrtypename = db.gettype(Ptr(T)) - self.ptrname = '((%s)(void*)%s)' % (cdecl(ptrtypename, ''), - self.ptrname) + if db.gettypedefnode(T).extra_union_for_varlength: + self.name += '.b' + self.ptrname = '(&%s)' % self.name def is_thread_local(self): return hasattr(self.T, "_hints") and self.T._hints.get('thread_local') + def get_declaration(self): + if self.name[-2:] == '.b': + # xxx fish fish + assert self.implementationtypename.startswith('struct ') + assert self.implementationtypename.endswith(' @') + uniontypename = 'union %su @' % self.implementationtypename[7:-2] + return uniontypename, self.name[:-2] + else: + return self.implementationtypename, self.name + def forward_declaration(self): if llgroup.member_of_group(self.obj): return + type, name = self.get_declaration() yield '%s;' % ( - forward_cdecl(self.implementationtypename, - self.name, self.db.standalone, self.is_thread_local())) + forward_cdecl(type, name, self.db.standalone, + self.is_thread_local())) def implementation(self): if llgroup.member_of_group(self.obj): return [] lines = list(self.initializationexpr()) + type, name = self.get_declaration() + if name != self.name: + lines[0] = '{ ' + lines[0] # extra braces around the 'a' part + lines[-1] += ' }' # of the union lines[0] = '%s = %s' % ( - cdecl(self.implementationtypename, self.name, self.is_thread_local()), + cdecl(type, name, self.is_thread_local()), lines[0]) lines[-1] += ';' return lines @@ -560,6 +595,7 @@ return 'struct _hashT_%s @' % self.name def forward_declaration(self): + assert self.typename == self.implementationtypename # no array part hash_typename = self.get_hash_typename() hash_offset = self.db.gctransformer.get_hash_offset(self.T) yield '%s {' % cdecl(hash_typename, '') @@ -675,6 +711,7 @@ return 1 # not variable-sized! def initializationexpr(self, decoration=''): + assert self.typename == self.implementationtypename # not var-sized is_empty = True yield '{' # _names == ['item0', 'item1', ...] From jandem at codespeak.net Wed Mar 24 17:57:28 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Wed, 24 Mar 2010 17:57:28 +0100 (CET) Subject: [pypy-svn] r72733 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100324165728.23B8F282BDC@codespeak.net> Author: jandem Date: Wed Mar 24 17:57:25 2010 New Revision: 72733 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Log: Add PyObject_{HasAttr, SetAttr}, simplify tests a bit Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 24 17:57:25 2010 @@ -396,5 +396,7 @@ int PyObject_IsTrue(PyObject *); int PyObject_Not(PyObject *); +int PyObject_HasAttr(PyObject *, PyObject *); +int PyObject_SetAttr(PyObject *, PyObject *, PyObject *); #endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 24 17:57:25 2010 @@ -5,7 +5,7 @@ from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject - +import pypy.module.__builtin__.operation as operation @cpython_api([PyObject], PyObject) def _PyObject_New(space, w_type): @@ -33,3 +33,13 @@ @cpython_api([PyObject], rffi.INT_real) def PyObject_Not(space, w_obj): return not space.is_true(w_obj) + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_HasAttr(space, w_obj, w_name): + w_res = operation.hasattr(space, w_obj, w_name) + return space.is_true(w_res) + + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real) +def PyObject_SetAttr(space, w_obj, w_name, w_value): + operation.setattr(space, w_obj, w_name, w_value) + return 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Wed Mar 24 17:57:25 2010 @@ -3,29 +3,64 @@ import py import sys + class AppTestObject(AppTestCpythonExtensionBase): def test_IsTrue(self): module = self.import_extension('foo', [ - ("test_IsTrue", "METH_VARARGS", + ("is_true", "METH_VARARGS", """ PyObject* arg = PyTuple_GetItem(args, 0); return PyBool_FromLong(PyObject_IsTrue(arg)); """), ]) - assert module.test_IsTrue(True) - assert module.test_IsTrue(1.0) - assert not module.test_IsTrue(False) - assert not module.test_IsTrue(0) + assert module.is_true(True) + assert module.is_true(1.0) + assert not module.is_true(False) + assert not module.is_true(0) def test_Not(self): module = self.import_extension('foo', [ - ("test_Not", "METH_VARARGS", + ("not_", "METH_VARARGS", """ PyObject* arg = PyTuple_GetItem(args, 0); return PyBool_FromLong(PyObject_Not(arg)); """), ]) - assert module.test_Not(False) - assert module.test_Not(0) - assert not module.test_Not(True) - assert not module.test_Not(3.14) + assert module.not_(False) + assert module.not_(0) + assert not module.not_(True) + assert not module.not_(3.14) + + def test_HasAttr(self): + module = self.import_extension('foo', [ + ("hasattr", "METH_VARARGS", + """ + PyObject* obj = PyTuple_GetItem(args, 0); + PyObject* name = PyTuple_GetItem(args, 1); + return PyBool_FromLong(PyObject_HasAttr(obj, name)); + """), + ]) + assert module.hasattr('', '__len__') + assert module.hasattr(int, '__eq__') + assert not module.hasattr(int, 'nonexistingattr') + + def test_SetAttr(self): + module = self.import_extension('foo', [ + ("setattr", "METH_VARARGS", + """ + PyObject* obj = PyTuple_GetItem(args, 0); + PyObject* name = PyTuple_GetItem(args, 1); + PyObject* value = PyTuple_GetItem(args, 2); + PyObject_SetAttr(obj, name, value); + Py_INCREF(Py_None); + return Py_None; + """), + ]) + class X: + pass + x = X() + module.setattr(x, 'test', 5) + assert hasattr(x, 'test') + assert x.test == 5 + module.setattr(x, 'test', 10) + assert x.test == 10 From arigo at codespeak.net Wed Mar 24 18:03:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:03:50 +0100 (CET) Subject: [pypy-svn] r72734 - pypy/branch/fix-64/pypy/translator/c/test Message-ID: <20100324170350.430AB282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:03:48 2010 New Revision: 72734 Modified: pypy/branch/fix-64/pypy/translator/c/test/test_newgc.py Log: Bah. Inverted the two arguments, which did not matter on 32-bit bits because they are both '4' there. Modified: pypy/branch/fix-64/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_newgc.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_newgc.py Wed Mar 24 18:03:48 2010 @@ -653,8 +653,8 @@ to_sort[2] = 1 to_sort[3] = 2 qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort)) - qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) qsort.push_arg(rffi.cast(rffi.SIZE_T, 4)) + qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) 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] From arigo at codespeak.net Wed Mar 24 18:12:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:12:03 +0100 (CET) Subject: [pypy-svn] r72737 - in pypy/branch/fix-64/pypy/rpython: lltypesystem test Message-ID: <20100324171203.0E0B3282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:12:01 2010 New Revision: 72737 Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/opimpl.py pypy/branch/fix-64/pypy/rpython/test/test_rbuiltin.py Log: Fix tests. Allow the op_xxx operations expecting a r_longlong to also accept a plain int on 64-bit platforms, and to always return a plain int. Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/branch/fix-64/pypy/rpython/lltypesystem/opimpl.py Wed Mar 24 18:12:01 2010 @@ -18,13 +18,20 @@ # global synonyms for some types from pypy.rlib.rarithmetic import intmask -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong -type_by_name = { +if r_longlong is r_int: + r_longlong_arg = (r_longlong, int) + r_longlong_result = int +else: + r_longlong_arg = r_longlong + r_longlong_result = r_longlong + +argtype_by_name = { 'int': int, 'float': float, 'uint': r_uint, - 'llong': r_longlong, + 'llong': r_longlong_arg, 'ullong': r_ulonglong, } @@ -56,9 +63,9 @@ adjust_result = intmask else: adjust_result = no_op - assert typname in type_by_name, "%s: not a primitive op" % ( + assert typname in argtype_by_name, "%s: not a primitive op" % ( fullopname,) - argtype = type_by_name[typname] + argtype = argtype_by_name[typname] if opname in ops_unary: def op_function(x): @@ -226,16 +233,16 @@ return r def op_llong_floordiv(x, y): - assert isinstance(x, r_longlong) - assert isinstance(y, r_longlong) + assert isinstance(x, r_longlong_arg) + assert isinstance(y, r_longlong_arg) r = x//y if x^y < 0 and x%y != 0: r += 1 return r def op_llong_mod(x, y): - assert isinstance(x, r_longlong) - assert isinstance(y, r_longlong) + assert isinstance(x, r_longlong_arg) + assert isinstance(y, r_longlong_arg) r = x%y if x^y < 0 and x%y != 0: r -= y @@ -258,7 +265,7 @@ return float(u) def op_cast_longlong_to_float(i): - assert type(i) is r_longlong + assert isinstance(i, r_longlong_arg) # take first 31 bits li = float(int(i & r_longlong(0x7fffffff))) ui = float(int(i >> 31)) * float(0x80000000) @@ -290,7 +297,7 @@ small = f / r high = int(small) truncated = int((small - high) * r) - return r_longlong(high) * 0x100000000 + truncated + return r_longlong_result(high) * 0x100000000 + truncated def op_cast_char_to_int(b): assert type(b) is str and len(b) == 1 @@ -314,10 +321,10 @@ def op_cast_int_to_longlong(b): assert type(b) is int - return r_longlong(b) + return r_longlong_result(b) def op_truncate_longlong_to_int(b): - assert type(b) is r_longlong + assert isinstance(b, r_longlong_arg) return intmask(b) def op_cast_pointer(RESTYPE, obj): Modified: pypy/branch/fix-64/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/branch/fix-64/pypy/rpython/test/test_rbuiltin.py Wed Mar 24 18:12:01 2010 @@ -5,7 +5,8 @@ from pypy.rlib.debug import llinterpcall from pypy.rpython.lltypesystem import lltype from pypy.tool import udir -from pypy.rlib.rarithmetic import r_uint, intmask, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong from pypy.annotation.builtin import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.lltypesystem import rffi @@ -526,11 +527,21 @@ return rffi.cast(rffi.VOIDP, v) res = self.interpret(llfn, [r_ulonglong(0)]) assert res == lltype.nullptr(rffi.VOIDP.TO) + # def llfn(v): return rffi.cast(rffi.LONGLONG, v) res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) assert res == 0 - assert isinstance(res, r_longlong) + if r_longlong is not r_int: + assert isinstance(res, r_longlong) + else: + assert isinstance(res, int) + # + def llfn(v): + return rffi.cast(rffi.ULONGLONG, v) + res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) + assert res == 0 + assert isinstance(res, r_ulonglong) class TestOOtype(BaseTestRbuiltin, OORtypeMixin): From arigo at codespeak.net Wed Mar 24 18:14:37 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:14:37 +0100 (CET) Subject: [pypy-svn] r72738 - pypy/branch/fix-64/pypy/rpython/test Message-ID: <20100324171437.EA283282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:14:36 2010 New Revision: 72738 Modified: pypy/branch/fix-64/pypy/rpython/test/test_rdict.py Log: Fix test. Modified: pypy/branch/fix-64/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/test/test_rdict.py (original) +++ pypy/branch/fix-64/pypy/rpython/test/test_rdict.py Wed Mar 24 18:14:36 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import rdict, rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.objectmodel import r_dict -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong import py py.log.setconsumer("rtyper", py.log.STDOUT) @@ -567,6 +567,8 @@ def test_dict_of_r_uint(self): for r_t in [r_uint, r_longlong, r_ulonglong]: + if r_t is r_int: + continue # for 64-bit platforms: skip r_longlong d = {r_t(2): 3, r_t(4): 5} def fn(x, y): d[r_t(x)] = 123 From arigo at codespeak.net Wed Mar 24 18:16:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:16:10 +0100 (CET) Subject: [pypy-svn] r72739 - pypy/branch/fix-64/pypy/rpython/test Message-ID: <20100324171610.C0E0C282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:16:09 2010 New Revision: 72739 Modified: pypy/branch/fix-64/pypy/rpython/test/test_rint.py Log: Fix test. Modified: pypy/branch/fix-64/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/test/test_rint.py (original) +++ pypy/branch/fix-64/pypy/rpython/test/test_rint.py Wed Mar 24 18:16:09 2010 @@ -110,10 +110,10 @@ def f(i): return str(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert self.ll_to_string(res) == '0' - res = self.interpret(f, [r_longlong(413974738222117)]) + res = self.interpret(f, [int64(413974738222117)]) assert self.ll_to_string(res) == '413974738222117' def test_unsigned(self): @@ -135,7 +135,7 @@ f._annspecialcase_ = "specialize:argtype(0)" def g(n): if n > 0: - return f(r_longlong(0)) + return f(int64(0)) else: return f(0) res = self.interpret(g, [0]) @@ -147,7 +147,7 @@ def test_downcast_int(self): def f(i): return int(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert res == 0 def test_isinstance_vs_int_types(self): From arigo at codespeak.net Wed Mar 24 18:24:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:24:43 +0100 (CET) Subject: [pypy-svn] r72740 - pypy/branch/fix-64/pypy/rpython/lltypesystem Message-ID: <20100324172443.B03B2282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:24:42 2010 New Revision: 72740 Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/lltype.py Log: Detect OverflowErrors and convert them to MemoryError when building a new _array. Fixes test_rlist.py. Modified: pypy/branch/fix-64/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/fix-64/pypy/rpython/lltypesystem/lltype.py Wed Mar 24 18:24:42 2010 @@ -1494,8 +1494,13 @@ if n < 0: raise ValueError, "negative array length" _parentable.__init__(self, TYPE) - self.items = [TYPE.OF._allocate(initialization=initialization, parent=self, parentindex=j) - for j in range(n)] + try: + myrange = range(n) + except OverflowError: + raise MemoryError("definitely too many items") + self.items = [TYPE.OF._allocate(initialization=initialization, + parent=self, parentindex=j) + for j in myrange] if parent is not None: self._setparentstructure(parent, parentindex) From afa at codespeak.net Wed Mar 24 18:49:55 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 18:49:55 +0100 (CET) Subject: [pypy-svn] r72742 - pypy/branch/cpython-extension/pypy/interpreter/test Message-ID: <20100324174955.CD82D282BDC@codespeak.net> Author: afa Date: Wed Mar 24 18:49:54 2010 New Revision: 72742 Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_typedef.py Log: Add test for r72611 Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_typedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_typedef.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_typedef.py Wed Mar 24 18:49:54 2010 @@ -1,5 +1,6 @@ from pypy.interpreter import typedef from pypy.tool.udir import udir +from pypy.interpreter.baseobjspace import Wrappable # this test isn't so much to test that the objspace interface *works* # -- it's more to test that it's *there* @@ -132,6 +133,17 @@ assert len(set) <= 6, "%s has %d subclasses:\n%r" % ( cls, len(set), [subcls.__name__ for subcls in set]) + def test_getsetproperty(self): + class W_SomeType(Wrappable): + pass + def fget(self, space, w_self): + assert self is prop + W_SomeType.typedef = typedef.TypeDef( + 'some_type', + x=typedef.GetSetProperty(fget, use_closure=True)) + w_obj = self.space.wrap(W_SomeType()) + assert self.space.getattr(w_obj, self.space.wrap('x')) is None + class AppTestTypeDef: From afa at codespeak.net Wed Mar 24 18:55:34 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 18:55:34 +0100 (CET) Subject: [pypy-svn] r72743 - in pypy/branch/cpython-extension/pypy: module/cpyext module/cpyext/include module/cpyext/test objspace/std Message-ID: <20100324175534.4078D282BDC@codespeak.net> Author: afa Date: Wed Mar 24 18:55:32 2010 New Revision: 72743 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py pypy/branch/cpython-extension/pypy/objspace/std/fake.py Log: more progress: - add a way to specify the value returned when RPython raises an exception - greatly simplify tests for the regular part of the C API: call it directly from interp-level. - Add support for PyErr_Clear() and PyErr_Occurred() - fix attribute access of FakedInstance objects, very useful in tests! Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 18:55:32 2010 @@ -43,14 +43,17 @@ setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) globals().update(rffi_platform.configure(CConfig_constants)) +_NOT_SPECIFIED = object() class ApiFunction: - def __init__(self, argtypes, restype, callable, borrowed): + def __init__(self, argtypes, restype, callable, borrowed, error): self.argtypes = argtypes self.restype = restype self.functype = lltype.Ptr(lltype.FuncType(argtypes, restype)) self.callable = callable self.borrowed = borrowed + if error is not _NOT_SPECIFIED: + self.error_value = error # extract the signature from the (CPython-level) code object from pypy.interpreter import pycode @@ -60,11 +63,12 @@ self.argnames = argnames[1:] assert len(self.argnames) == len(self.argtypes) +def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED): + if restype is PyObject and error is _NOT_SPECIFIED: + error = None -def cpython_api(argtypes, restype, borrowed=False): def decorate(func): - api_function = ApiFunction(argtypes, restype, func, borrowed) - FUNCTIONS[func.func_name] = api_function + api_function = ApiFunction(argtypes, restype, func, borrowed, error) def unwrapper(space, *args): "NOT_RPYTHON: XXX unsure" @@ -82,6 +86,14 @@ newargs.append(arg) try: return func(space, *newargs) + except OperationError, e: + if not hasattr(api_function, "error_value"): + raise + state = space.fromcache(State) + e.normalize_exception(space) + state.exc_type = e.w_type + state.exc_value = e.get_w_value(space) + return api_function.error_value finally: from pypy.module.cpyext.macros import Py_DECREF for arg in to_decref: @@ -89,6 +101,8 @@ func.api_func = api_function unwrapper.api_func = api_function + FUNCTIONS[func.func_name] = api_function + INTERPLEVEL_API[func.func_name] = unwrapper return unwrapper return decorate @@ -105,6 +119,7 @@ TYPES[configname] = forward return forward +INTERPLEVEL_API = {} FUNCTIONS = {} FUNCTIONS_C = {} TYPES = {} Modified: pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py Wed Mar 24 18:55:32 2010 @@ -5,6 +5,6 @@ def PyFloat_FromDouble(space, value): return space.wrap(value) - at cpython_api([PyObject], lltype.Float) + at cpython_api([PyObject], lltype.Float, error=-1) def PyFloat_AsDouble(space, w_obj): return space.float_w(space.float(w_obj)) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Wed Mar 24 18:55:32 2010 @@ -9,6 +9,8 @@ PyAPI_DATA(PyObject *) PyExc_Exception; void PyErr_SetString(PyObject *, char *); +PyObject * PyErr_Occurred(void); +void PyErr_Clear(PyObject *, char *); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 24 18:55:32 2010 @@ -26,11 +26,11 @@ obj_voidp = rffi.cast(rffi.VOIDP_real, obj) generic_cpy_call(space, pto.c_tp_free, obj_voidp) - at cpython_api([PyObject], rffi.INT_real) + at cpython_api([PyObject], rffi.INT_real, error=-1) def PyObject_IsTrue(space, w_obj): return space.is_true(w_obj) - at cpython_api([PyObject], rffi.INT_real) + at cpython_api([PyObject], rffi.INT_real, error=-1) def PyObject_Not(space, w_obj): return not space.is_true(w_obj) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 24 18:55:32 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, PyObject, make_ref - +from pypy.module.cpyext.state import State @cpython_api([PyObject, rffi.CCHARP], lltype.Void) def PyErr_SetString(space, w_type, message_ptr): @@ -9,6 +9,16 @@ w_obj = space.call_function(w_type, space.wrap(message)) raise OperationError(w_type, w_obj) + at cpython_api([], PyObject) +def PyErr_Occurred(space): + state = space.fromcache(State) + return state.exc_value + + at cpython_api([], lltype.Void) +def PyErr_Clear(space): + state = space.fromcache(State) + state.exc_type = None + state.exc_value = None @cpython_api([], lltype.Void) def PyErr_BadInternalCall(space): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py Wed Mar 24 18:55:32 2010 @@ -6,3 +6,7 @@ if option.runappdirect: py.test.skip("cannot be run by py.test -A") return super(Directory, self).collect() + +def pytest_funcarg__api(request): + return request.cls.api + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 24 18:55:32 2010 @@ -54,6 +54,18 @@ standalone=False) return str(soname) +class BaseApiTest: + def setup_class(cls): + class CAPI: + def __getattr__(self, name): + return getattr(cls.space, name) + cls.api = CAPI() + CAPI.__dict__.update(api.INTERPLEVEL_API) + + def teardown_method(self, func): + state = self.space.fromcache(State) + assert state.exc_value is None + class AppTestCpythonExtensionBase: def setup_class(cls): cls.space = gettestobjspace(usemodules=['cpyext']) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Wed Mar 24 18:55:32 2010 @@ -1,22 +1,9 @@ -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from pypy.module.cpyext.test.test_cpyext import BaseApiTest -import py -import sys +class TestFloatObject(BaseApiTest): + def test_floatobject(self, space, api): + assert space.unwrap(api.PyFloat_FromDouble(3.14)) == 3.14 + assert api.PyFloat_AsDouble(space.wrap(23.45)) == 23.45 -class AppTestFloatObject(AppTestCpythonExtensionBase): - def test_floatobject(self): - module = self.import_extension('foo', [ - ("FromDouble", "METH_NOARGS", - """ - return PyFloat_FromDouble(3.14); - """), - ("AsDouble", "METH_NOARGS", - """ - PyObject* obj = PyFloat_FromDouble(23.45); - double d = PyFloat_AsDouble(obj); - Py_DECREF(obj); - return PyFloat_FromDouble(d); - """), - ]) - assert module.FromDouble() == 3.14 - assert module.AsDouble() == 23.45 + assert api.PyFloat_AsDouble(space.w_None) == -1 + api.PyErr_Clear() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Wed Mar 24 18:55:32 2010 @@ -1,66 +1,40 @@ -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from pypy.module.cpyext.test.test_cpyext import BaseApiTest -import py -import sys +class TestObject(BaseApiTest): + def test_IsTrue(self, space, api): + assert api.PyObject_IsTrue(space.wrap(1.0)) == 1 + assert api.PyObject_IsTrue(space.wrap(False)) == 0 + assert api.PyObject_IsTrue(space.wrap(0)) == 0 + + def test_Not(self, space, api): + assert api.PyObject_Not(space.wrap(False)) == 1 + assert api.PyObject_Not(space.wrap(0)) == 1 + assert api.PyObject_Not(space.wrap(True)) == 0 + assert api.PyObject_Not(space.wrap(3.14)) == 0 + + def test_exception(self, space, api): + class C: + def __nonzero__(self): + raise ValueError + + assert api.PyObject_IsTrue(space.wrap(C())) == -1 + assert api.PyObject_Not(space.wrap(C())) == -1 + api.PyErr_Clear() + + def test_HasAttr(self, space, api): + hasattr_ = lambda w_obj, name: api.PyObject_HasAttr(w_obj, + space.wrap(name)) + assert hasattr_(space.wrap(''), '__len__') + assert hasattr_(space.w_int, '__eq__') + assert not hasattr_(space.w_int, 'nonexistingattr') - -class AppTestObject(AppTestCpythonExtensionBase): - def test_IsTrue(self): - module = self.import_extension('foo', [ - ("is_true", "METH_VARARGS", - """ - PyObject* arg = PyTuple_GetItem(args, 0); - return PyBool_FromLong(PyObject_IsTrue(arg)); - """), - ]) - assert module.is_true(True) - assert module.is_true(1.0) - assert not module.is_true(False) - assert not module.is_true(0) - - def test_Not(self): - module = self.import_extension('foo', [ - ("not_", "METH_VARARGS", - """ - PyObject* arg = PyTuple_GetItem(args, 0); - return PyBool_FromLong(PyObject_Not(arg)); - """), - ]) - assert module.not_(False) - assert module.not_(0) - assert not module.not_(True) - assert not module.not_(3.14) - - def test_HasAttr(self): - module = self.import_extension('foo', [ - ("hasattr", "METH_VARARGS", - """ - PyObject* obj = PyTuple_GetItem(args, 0); - PyObject* name = PyTuple_GetItem(args, 1); - return PyBool_FromLong(PyObject_HasAttr(obj, name)); - """), - ]) - assert module.hasattr('', '__len__') - assert module.hasattr(int, '__eq__') - assert not module.hasattr(int, 'nonexistingattr') - - def test_SetAttr(self): - module = self.import_extension('foo', [ - ("setattr", "METH_VARARGS", - """ - PyObject* obj = PyTuple_GetItem(args, 0); - PyObject* name = PyTuple_GetItem(args, 1); - PyObject* value = PyTuple_GetItem(args, 2); - PyObject_SetAttr(obj, name, value); - Py_INCREF(Py_None); - return Py_None; - """), - ]) + def test_SetAttr(self, space, api): class X: pass x = X() - module.setattr(x, 'test', 5) - assert hasattr(x, 'test') + api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(5)) + assert not api.PyErr_Occurred() assert x.test == 5 - module.setattr(x, 'test', 10) + assert api.PyObject_HasAttr(space.wrap(x), space.wrap('test')) + api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(10)) assert x.test == 10 Modified: pypy/branch/cpython-extension/pypy/objspace/std/fake.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/fake.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/fake.py Wed Mar 24 18:55:32 2010 @@ -114,6 +114,9 @@ cpy_type.__name__, base, **kw) def __init__(w_self, space, val): w_self.val = val + w_self.space = space + def getdict(w_self): + return w_self.space.wrap(w_self.val.__dict__) def unwrap(w_self, space): return w_self.val W_Fake.__name__ = 'W_Fake%s'%(cpy_type.__name__.capitalize()) From arigo at codespeak.net Wed Mar 24 18:57:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 18:57:15 +0100 (CET) Subject: [pypy-svn] r72744 - pypy/branch/fix-64/pypy/objspace/std Message-ID: <20100324175715.9BE1A282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 18:57:14 2010 New Revision: 72744 Modified: pypy/branch/fix-64/pypy/objspace/std/typeobject.py Log: Make this algo very slightly more complicated, with an explanation for the reason. Modified: pypy/branch/fix-64/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/fix-64/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/fix-64/pypy/objspace/std/typeobject.py Wed Mar 24 18:57:14 2010 @@ -264,7 +264,8 @@ @purefunction def _pure_lookup_where_with_method_cache(w_self, name, version_tag): space = w_self.space - SHIFT = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + SHIFT2 = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + SHIFT1 = SHIFT2 - 5 version_tag_as_int = current_object_addr_as_int(version_tag) # ^^^Note: if the version_tag object is moved by a moving GC, the # existing method cache entries won't be found any more; new @@ -273,7 +274,12 @@ # the time - so using the fast current_object_addr_as_int() instead # of a slower solution like hash() is still a good trade-off. hash_name = compute_hash(name) - method_hash = r_uint(intmask(version_tag_as_int * hash_name)) >> SHIFT + product = intmask(version_tag_as_int * hash_name) + method_hash = (r_uint(product) ^ (r_uint(product) << SHIFT1)) >> SHIFT2 + # ^^^Note2: we used to just take product>>SHIFT2, but on 64-bit + # platforms SHIFT2 is really large, and we loose too much information + # that way (as shown by failures of the tests that typically have + # method names like 'f' who hash to a number that has only ~33 bits). cached_version_tag = space.method_cache_versions[method_hash] if cached_version_tag is version_tag: cached_name = space.method_cache_names[method_hash] From arigo at codespeak.net Wed Mar 24 19:00:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 19:00:18 +0100 (CET) Subject: [pypy-svn] r72745 - pypy/branch/fix-64/pypy/module/readline/test Message-ID: <20100324180018.33FA1282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 19:00:16 2010 New Revision: 72745 Modified: pypy/branch/fix-64/pypy/module/readline/test/test_c_readline.py pypy/branch/fix-64/pypy/module/readline/test/test_with_pypy.py Log: Skip these tests if readline/readline.h is not installed. Modified: pypy/branch/fix-64/pypy/module/readline/test/test_c_readline.py ============================================================================== --- pypy/branch/fix-64/pypy/module/readline/test/test_c_readline.py (original) +++ pypy/branch/fix-64/pypy/module/readline/test/test_c_readline.py Wed Mar 24 19:00:16 2010 @@ -2,8 +2,14 @@ Directly test the basic ctypes wrappers. """ +import py from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() -from pypy.module.readline import c_readline +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) def test_basic_import(): Modified: pypy/branch/fix-64/pypy/module/readline/test/test_with_pypy.py ============================================================================== --- pypy/branch/fix-64/pypy/module/readline/test/test_with_pypy.py (original) +++ pypy/branch/fix-64/pypy/module/readline/test/test_with_pypy.py Wed Mar 24 19:00:16 2010 @@ -3,7 +3,14 @@ in the PyPy interpreter, itself running on top of CPython """ +import py from pypy.conftest import gettestobjspace +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) class AppTestReadline: From arigo at codespeak.net Wed Mar 24 19:05:32 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 19:05:32 +0100 (CET) Subject: [pypy-svn] r72746 - pypy/branch/fix-64/pypy/module/_socket/test Message-ID: <20100324180532.D5718282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 19:05:31 2010 New Revision: 72746 Modified: pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py Log: Semi-random: accept the result we got on the tannit machine. Modified: pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py ============================================================================== --- pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py (original) +++ pypy/branch/fix-64/pypy/module/_socket/test/test_sock_app.py Wed Mar 24 19:05:31 2010 @@ -32,13 +32,17 @@ def test_gethostbyaddr(): host = "localhost" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds host = "127.0.0.1" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds def test_getservbyname(): name = "smtp" From arigo at codespeak.net Wed Mar 24 19:06:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 19:06:55 +0100 (CET) Subject: [pypy-svn] r72747 - pypy/branch/fix-64/pypy/lib/app_test Message-ID: <20100324180655.D1EA3282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 19:06:54 2010 New Revision: 72747 Modified: pypy/branch/fix-64/pypy/lib/app_test/test_dbm_extra.py Log: Skip the test if dbm cannot be found. Modified: pypy/branch/fix-64/pypy/lib/app_test/test_dbm_extra.py ============================================================================== --- pypy/branch/fix-64/pypy/lib/app_test/test_dbm_extra.py (original) +++ pypy/branch/fix-64/pypy/lib/app_test/test_dbm_extra.py Wed Mar 24 19:06:54 2010 @@ -1,6 +1,9 @@ import py -from pypy.lib import dbm from pypy.tool.udir import udir +try: + from pypy.lib import dbm +except ImportError, e: + py.test.skip(e) def test_get(): path = str(udir.join('test_dbm_extra.test_get')) From afa at codespeak.net Wed Mar 24 20:11:05 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 20:11:05 +0100 (CET) Subject: [pypy-svn] r72748 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100324191105.A4D5B282BDC@codespeak.net> Author: afa Date: Wed Mar 24 20:11:03 2010 New Revision: 72748 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/boolobject.py pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/pythonrun.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Change exception handling in cpyext: - ensure that every C function properly declares its error value - check consistency between the return value and the exception stored in the threadstate - remove from_ref_ex(), not needed any more. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 20:11:03 2010 @@ -44,6 +44,7 @@ globals().update(rffi_platform.configure(CConfig_constants)) _NOT_SPECIFIED = object() +CANNOT_FAIL = object() class ApiFunction: def __init__(self, argtypes, restype, callable, borrowed, error): @@ -64,12 +65,18 @@ assert len(self.argnames) == len(self.argtypes) def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED): - if restype is PyObject and error is _NOT_SPECIFIED: - error = None + if error is _NOT_SPECIFIED: + if restype is PyObject: + error = lltype.nullptr(PyObject.TO) + elif restype is lltype.Void: + error = CANNOT_FAIL def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed, error) + if error is _NOT_SPECIFIED: + raise ValueError("function %s has no return value for exceptions" + % func) def unwrapper(space, *args): "NOT_RPYTHON: XXX unsure" newargs = [] @@ -171,7 +178,6 @@ def make_ref(space, w_obj, borrowed=False): if w_obj is None: return lltype.nullptr(PyObject.TO) - #raise NullPointerException("Trying to pass a NULL reference") assert isinstance(w_obj, W_Root) state = space.fromcache(State) py_obj = state.py_objects_w2r.get(w_obj) @@ -209,9 +215,9 @@ return py_obj def from_ref(space, ref): - state = space.fromcache(State) if not ref: - raise NullPointerException("Null pointer dereference!") + return None + state = space.fromcache(State) ptr = ctypes.addressof(ref._obj._storage) try: obj = state.py_objects_r2w[ptr] @@ -251,24 +257,25 @@ retval = callable(space, *boxed_args) print >>sys.stderr, " DONE" except OperationError, e: + failed = True e.normalize_exception(space) state.exc_type = e.w_type state.exc_value = e.get_w_value(space) except BaseException, e: + failed = True state.exc_type = space.w_SystemError state.exc_value = space.wrap(str(e)) import traceback traceback.print_exc() + else: + failed = False - if state.exc_value is not None: - restype = callable.api_func.restype - if restype is lltype.Void: - return - if restype is PyObject: - return lltype.nullptr(PyObject.TO) - if restype in (Py_ssize_t, rffi.INT_real): - return rffi.cast(restype, -1) - assert False, "Unknown return type" + if failed: + error_value = callable.api_func.error_value + if error_value is CANNOT_FAIL: + raise SystemError("The function %r was not supposed to fail" + % (callable,)) + return error_value if callable.api_func.restype is PyObject: retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) @@ -413,6 +420,8 @@ def generic_cpy_call(space, func, *args, **kwargs): from pypy.module.cpyext.macros import Py_DECREF + from pypy.module.cpyext.pyerrors import PyErr_Occurred + decref_args = kwargs.pop("decref_args", True) assert not kwargs boxed_args = [] @@ -424,9 +433,24 @@ result = func(*boxed_args) try: FT = lltype.typeOf(func).TO - if FT.RESULT is not lltype.Void: - ret = from_ref_ex(space, result) - Py_DECREF(space, ret) + if FT.RESULT is PyObject: + ret = from_ref(space, result) + + # Check for exception consistency + has_error = PyErr_Occurred(space) is not None + has_result = ret is not None + if has_error and has_result: + raise OperationError(space.w_SystemError, space.wrap( + "An exception was set, but function returned a value")) + elif not has_error and not has_result: + raise OperationError(space.w_SystemError, space.wrap( + "Function returned a NULL result without setting an exception")) + + if has_error: + state = space.fromcache(State) + state.check_and_raise_exception() + + Py_DECREF(space, ret) # XXX WHY?? return ret finally: if decref_args: @@ -434,19 +458,3 @@ if arg is not None and isinstance(arg, W_Root): Py_DECREF(space, arg) -def from_ref_ex(space, result): - try: - ret = from_ref(space, result) - except NullPointerException: - state = space.fromcache(State) - state.check_and_raise_exception() - assert False, "NULL returned but no exception set" - except InvalidPointerException: - if not we_are_translated(): - import sys - print >>sys.stderr, "Calling a C function return an invalid PyObject" \ - " pointer." - raise - return ret - - Modified: pypy/branch/cpython-extension/pypy/module/cpyext/boolobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/boolobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/boolobject.py Wed Mar 24 20:11:03 2010 @@ -1,7 +1,8 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, general_check +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL +from pypy.module.cpyext.api import general_check - at cpython_api([PyObject], rffi.INT_real) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyBool_Check(space, w_obj): w_type = space.w_bool return general_check(space, w_obj, w_type) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 24 20:11:03 2010 @@ -1,19 +1,19 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @cpython_api([], PyObject) def PyDict_New(space): return space.newdict() - at cpython_api([PyObject], rffi.INT_real) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyDict_Check(space, w_obj): w_type = space.w_dict w_obj_type = space.type(w_obj) return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) - at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real) + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real, error=-1) def PyDict_SetItemString(space, w_dict, key_ptr, w_obj): if PyDict_Check(space, w_dict): key = rffi.charp2str(key_ptr) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Wed Mar 24 20:11:03 2010 @@ -10,7 +10,7 @@ PyAPI_DATA(PyObject *) PyExc_Exception; void PyErr_SetString(PyObject *, char *); PyObject * PyErr_Occurred(void); -void PyErr_Clear(PyObject *, char *); +void PyErr_Clear(); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Wed Mar 24 20:11:03 2010 @@ -4,11 +4,13 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec +from pypy.interpreter.error import OperationError from pypy.interpreter.function import BuiltinFunction, Method from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, \ - make_ref, generic_cpy_call, from_ref_ex + make_ref, generic_cpy_call from pypy.module.cpyext.state import State +from pypy.module.cpyext.pyerrors import PyErr_Occurred from pypy.rlib.objectmodel import we_are_translated Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 24 20:11:03 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - METH_STATIC, METH_CLASS, METH_COEXIST, general_check + METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @@ -69,7 +69,7 @@ dict_w[methodname] = w_obj - at cpython_api([PyObject], rffi.INT_real) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyModule_Check(space, w_obj): w_type = space.gettypeobject(Module.typedef) return general_check(space, w_obj, w_type) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 24 20:11:03 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ - generic_cpy_call + generic_cpy_call, CANNOT_FAIL from pypy.module.cpyext.state import State from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject @@ -34,12 +34,12 @@ def PyObject_Not(space, w_obj): return not space.is_true(w_obj) - at cpython_api([PyObject, PyObject], rffi.INT_real) + at cpython_api([PyObject, PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyObject_HasAttr(space, w_obj, w_name): w_res = operation.hasattr(space, w_obj, w_name) return space.is_true(w_res) - at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real) + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1) def PyObject_SetAttr(space, w_obj, w_name, w_value): operation.setattr(space, w_obj, w_name, w_value) return 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 24 20:11:03 2010 @@ -6,8 +6,9 @@ @cpython_api([PyObject, rffi.CCHARP], lltype.Void) def PyErr_SetString(space, w_type, message_ptr): message = rffi.charp2str(message_ptr) - w_obj = space.call_function(w_type, space.wrap(message)) - raise OperationError(w_type, w_obj) + state = space.fromcache(State) + state.exc_type = w_type + state.exc_value = space.call_function(w_type, space.wrap(message)) @cpython_api([], PyObject) def PyErr_Occurred(space): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pythonrun.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pythonrun.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pythonrun.py Wed Mar 24 20:11:03 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api +from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL - at cpython_api([], rffi.INT_real) + at cpython_api([], rffi.INT_real, error=CANNOT_FAIL) def Py_IsInitialized(space): return 1 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Wed Mar 24 20:11:03 2010 @@ -11,6 +11,6 @@ s = rffi.charp2str(char_p) return space.wrap(s) - at cpython_api([PyObject], Py_ssize_t) + at cpython_api([PyObject], Py_ssize_t, error=-1) def PyString_Size(space, w_obj): return space.int_w(space.len(w_obj)) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 24 20:11:03 2010 @@ -17,7 +17,7 @@ def PyPy_Crash1(space): 1/0 - at api.cpython_api([], lltype.Signed) + at api.cpython_api([], lltype.Signed, error=-1) def PyPy_Crash2(space): 1/0 @@ -366,7 +366,6 @@ def test_internal_exceptions(self): - skip("Useful to see how programming errors look like") import sys init = """ if (Py_IsInitialized()) @@ -384,14 +383,41 @@ return NULL; return PyFloat_FromDouble(a); } + static PyObject* foo_crash3(PyObject* self, PyObject *args) + { + int a = PyPy_Crash2(); + if (a == -1) + PyErr_Clear(); + return PyFloat_FromDouble(a); + } + static PyObject* foo_crash4(PyObject* self, PyObject *args) + { + int a = PyPy_Crash2(); + return PyFloat_FromDouble(a); + } + static PyObject* foo_clear(PyObject* self, PyObject *args) + { + PyErr_Clear(); + return NULL; + } static PyMethodDef methods[] = { { "crash1", foo_crash1, METH_NOARGS }, { "crash2", foo_crash2, METH_NOARGS }, + { "crash3", foo_crash3, METH_NOARGS }, + { "crash4", foo_crash4, METH_NOARGS }, + { "clear", foo_clear, METH_NOARGS }, { NULL } }; """ module = self.import_module(name='foo', init=init, body=body) - module.crash1() - module.crash2() + # uncaught interplevel exceptions are turned into SystemError + raises(SystemError, module.crash1) + raises(SystemError, module.crash2) + # caught exception + assert module.crash3() == -1 + # An exception was set, but function returned a value + raises(SystemError, module.crash4) + # No exception set, but NULL returned + raises(SystemError, module.clear) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Wed Mar 24 20:11:03 2010 @@ -8,7 +8,7 @@ def PyTuple_New(space, size): return space.newtuple([space.w_None] * size) - at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real) + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) def PyTuple_SetItem(space, w_t, pos, w_obj): assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Wed Mar 24 20:11:03 2010 @@ -16,7 +16,7 @@ from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State -from pypy.module.cpyext.methodobject import from_ref_ex, generic_cpy_call +from pypy.module.cpyext.methodobject import generic_cpy_call PyTypeObject = lltype.ForwardReference() @@ -238,7 +238,7 @@ def PyType_Ready(space, pto): "Implemented in typeobject.c" - at cpython_api([PyTypeObjectPtr], rffi.INT_real) + at cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1) def PyPyType_Register(space, pto): state = space.fromcache(State) ptr = ctypes.addressof(pto._obj._storage) From xoraxax at codespeak.net Wed Mar 24 21:47:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 21:47:09 +0100 (CET) Subject: [pypy-svn] r72757 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324204709.67BFC282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 21:47:07 2010 New Revision: 72757 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Make debug message more useful. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Wed Mar 24 21:47:07 2010 @@ -28,7 +28,7 @@ state = space.fromcache(State) pto = obj.c_obj_type pto = rffi.cast(PyTypeObjectPtr, pto) - print "Calling ", pto.c_tp_dealloc, "of", obj, \ + print "Calling dealloc slot of", obj, \ "'s type which is", rffi.charp2str(pto.c_tp_name) generic_cpy_call(space, pto.c_tp_dealloc, obj, decref_args=False) From xoraxax at codespeak.net Wed Mar 24 22:05:01 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:05:01 +0100 (CET) Subject: [pypy-svn] r72758 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100324210501.D6160282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:05:00 2010 New Revision: 72758 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Gah, the new exception handling is annoying. Can you please fix this test, amaury? The exception of PyErr_BadInternallCall is eaten. Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Wed Mar 24 22:05:00 2010 @@ -0,0 +1,11 @@ +import py.test + +from pypy.module.cpyext.test.test_cpyext import BaseApiTest + +class TestTupleObject(BaseApiTest): + def test_tupleobject(self, space, api): + assert not api.PyTuple_Check(space.w_None) + py.test.raises(TypeError, api.PyTuple_SetItem, space.w_None, + 0, space.w_None) + api.PyTuple_SetItem(space.w_None, 0, space.w_None) + #api.PyErr_Clear() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Wed Mar 24 22:05:00 2010 @@ -1,8 +1,14 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t +from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \ + general_check, CANNOT_FAIL from pypy.module.cpyext.macros import Py_DECREF +from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.tupleobject import W_TupleObject + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyTuple_Check(space, w_obj): + w_type = space.w_tuple + return general_check(space, w_obj, w_type) @cpython_api([Py_ssize_t], PyObject) def PyTuple_New(space, size): @@ -10,13 +16,15 @@ @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) def PyTuple_SetItem(space, w_t, pos, w_obj): - assert isinstance(w_t, W_TupleObject) + if not PyTuple_Check(space, w_t): + PyErr_BadInternalCall(space) + assert isinstance(w_t, W_TupleObject) # XXX add check here w_t.wrappeditems[pos] = w_obj - Py_DECREF(space, w_obj) # SetItem steals a reference! + Py_DECREF(space, w_obj) # SetItem steals a reference! XXX this needs to go into the wrapper return 0 @cpython_api([PyObject, Py_ssize_t], PyObject) def PyTuple_GetItem(space, w_t, pos): - assert isinstance(w_t, W_TupleObject) + assert isinstance(w_t, W_TupleObject) # XXX add check here w_obj = w_t.wrappeditems[pos] return w_obj From xoraxax at codespeak.net Wed Mar 24 22:05:38 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:05:38 +0100 (CET) Subject: [pypy-svn] r72759 - pypy/branch/cpython-extension/pypy/interpreter Message-ID: <20100324210538.034E6282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:05:37 2010 New Revision: 72759 Modified: pypy/branch/cpython-extension/pypy/interpreter/argument.py Log: Removed unpack_cpy. Modified: pypy/branch/cpython-extension/pypy/interpreter/argument.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/argument.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/argument.py Wed Mar 24 22:05:37 2010 @@ -128,19 +128,6 @@ kwds_w[self.keywords[i]] = self.keywords_w[i] return self.arguments_w, kwds_w - def unpack_cpy(self, starting_at=0): - assert starting_at >= 0 - space = self.space - args_w = self.arguments_w - w_kw = space.newdict() - if self.keywords: - for i in range(len(self.keywords)): - space.setitem(w_kw, space.wrap(self.keywords[i]), self.keywords_w[i]) - if starting_at != 0: - args_w = args_w[starting_at:] - args_tuple = space.newtuple([space.wrap(args_w), w_kw]) - return args_tuple - def replace_arguments(self, args_w): "Return a new Arguments with a args_w as positional arguments." return Arguments(self.space, args_w, self.keywords, self.keywords_w) From xoraxax at codespeak.net Wed Mar 24 22:14:06 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:14:06 +0100 (CET) Subject: [pypy-svn] r72760 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324211406.8DBBB282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:14:05 2010 New Revision: 72760 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: Remove old comments. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Wed Mar 24 22:14:05 2010 @@ -14,7 +14,6 @@ from pypy.rlib.objectmodel import we_are_translated -# XXX use Function as a parent class? class W_PyCFunctionObject(Wrappable): def __init__(self, space, ml, w_self): self.space = space @@ -68,9 +67,6 @@ return ret def cmethod_descr_get(space, w_function, w_obj, w_cls=None): - """functionobject.__get__(obj[, type]) -> method""" - # this is not defined as a method on Function because it's generally - # useful logic: w_function can be any callable. It is used by Method too. asking_for_bound = (space.is_w(w_cls, space.w_None) or not space.is_w(w_obj, space.w_None) or space.is_w(w_cls, space.type(space.w_None))) From xoraxax at codespeak.net Wed Mar 24 22:15:24 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:15:24 +0100 (CET) Subject: [pypy-svn] r72761 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100324211524.53EB6282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:15:22 2010 New Revision: 72761 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Support non-external functions. These are the ones that would be declared static in the CPython code (yes, not really part of the API but I need them to fill the slots). Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Wed Mar 24 22:15:22 2010 @@ -1,7 +1,6 @@ - Generate header files programmatically. - Implement C API. - Complete the PyTypeObject initialization code. - - Free pto.c_tp_name correctly - properly support "borrowed" references: the PyObject must be stored somewhere - lltype.free in PyObject_Del() sometimes raise an exception (but all Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 22:15:22 2010 @@ -38,6 +38,7 @@ constant_names = """ Py_TPFLAGS_READY Py_TPFLAGS_READYING METH_COEXIST METH_STATIC METH_CLASS METH_NOARGS +Py_TPFLAGS_HEAPTYPE """.split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) @@ -64,7 +65,7 @@ self.argnames = argnames[1:] assert len(self.argnames) == len(self.argtypes) -def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED): +def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True): if error is _NOT_SPECIFIED: if restype is PyObject: error = lltype.nullptr(PyObject.TO) @@ -108,7 +109,9 @@ func.api_func = api_function unwrapper.api_func = api_function - FUNCTIONS[func.func_name] = api_function + unwrapper.func = func + if external: + FUNCTIONS[func.func_name] = api_function INTERPLEVEL_API[func.func_name] = unwrapper return unwrapper return decorate @@ -190,7 +193,7 @@ if space.is_w(w_type, w_obj): pto = py_obj else: - pto = make_ref(space, w_type, borrowed=True) + pto = make_ref(space, w_type) elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) @@ -200,7 +203,7 @@ py_obj = lltype.malloc(T, None, flavor="raw") else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") - pto = make_ref(space, space.type(w_obj), borrowed=True) + pto = make_ref(space, space.type(w_obj)) py_obj.c_obj_type = rffi.cast(PyObject, pto) py_obj.c_obj_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) @@ -304,6 +307,8 @@ renamed_symbols = [] if rename: for name in export_symbols: + if name.startswith("PyPy"): + continue if "#" in name: deref = "*" else: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 24 22:15:22 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \ + general_check from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @cpython_api([], PyObject) @@ -9,8 +10,7 @@ @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) def PyDict_Check(space, w_obj): w_type = space.w_dict - w_obj_type = space.type(w_obj) - return space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type)) + return general_check(space, w_obj, w_type) @cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real, error=-1) @@ -22,4 +22,4 @@ space.setitem(w_dict, space.wrap(key), w_obj) return 0 else: - PyErr_BadInternalCall() + PyErr_BadInternalCall(space) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 24 22:15:22 2010 @@ -80,4 +80,4 @@ assert isinstance(w_mod, Module) return w_mod.getdict() else: - PyErr_BadInternalCall() + PyErr_BadInternalCall(space) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 24 22:15:22 2010 @@ -139,6 +139,7 @@ self.space.wrap('foo')) self.space.delitem(self.space.sys.get('modules'), self.space.wrap('foo')) + Py_DECREF(self.space, w_mod) except OperationError: pass self.space.fromcache(State).print_refcounts() @@ -372,6 +373,8 @@ Py_InitModule("foo", methods); """ body = """ + PyObject* PyPy_Crash1(void); + long PyPy_Crash2(void); static PyObject* foo_crash1(PyObject* self, PyObject *args) { return PyPy_Crash1(); Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Wed Mar 24 22:15:22 2010 @@ -12,7 +12,7 @@ from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY -from pypy.module.cpyext.api import make_wrapper +from pypy.module.cpyext.api import make_wrapper, Py_TPFLAGS_HEAPTYPE from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State @@ -215,22 +215,57 @@ w_type = space.type(self) assert isinstance(w_type, W_PyCTypeObject) pto = w_type.pto + print "Called W_PyCObject.__del__" generic_cpy_call(space, pto.c_tp_dealloc, self) + at cpython_api([PyObject], lltype.Void, external=False) +def subtype_dealloc(space, obj): + pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE + base = pto + #basedealloc = pto.c_tp_dealloc + # XXX lookup basedealloc which is not subtype_dealloc + # XXX call tp_del if necessary + # XXX call basedealloc instead of a fixed type_dealloc + type_dealloc(space, obj) + Py_DECREF(space, pto) + + + at cpython_api([PyObject], lltype.Void, external=False) +def type_dealloc(space, obj): + print "type_dealloc of", obj + obj_pto = rffi.cast(PyTypeObjectPtr, obj) + type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + # type_dealloc code follows: + # XXX XDECREF tp_base, tp_dict, tp_bases, tp_mro, tp_cache, + # tp_subclasses + # free tp_doc + lltype.free(obj_pto.c_tp_name, flavor="raw") + generic_cpy_call(space, type_pto.c_tp_free, obj) + + def allocate_type_obj(space, w_type): + """ Allocates a pto from a w_type which must be a PyPy type. """ from pypy.module.cpyext.object import PyObject_dealloc, PyObject_Del + assert not isinstance(w_type, W_PyCTypeObject) pto = lltype.malloc(PyTypeObject, None, flavor="raw") - callable = PyObject_dealloc - pto.c_tp_dealloc = llhelper(callable.api_func.functype, - make_wrapper(space, callable)) + if space.is_w(w_type, space.w_type): + callable = subtype_dealloc + pto.c_tp_dealloc = llhelper(callable.api_func.functype, + make_wrapper(space, callable)) + else: + callable = PyObject_dealloc + pto.c_tp_dealloc = llhelper(callable.api_func.functype, + make_wrapper(space, callable)) + print "Chose dealloc strategy %r for %r" % (callable.func, w_type) callable = PyObject_Del + pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE pto.c_tp_free = llhelper(callable.api_func.functype, make_wrapper(space, callable)) - # XXX free c_tp_name again! pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) - pto.c_tp_basicsize = -1 # hopefully this makes malloc bail + pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out # XXX fill slots in pto return pto From xoraxax at codespeak.net Wed Mar 24 22:17:25 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:17:25 +0100 (CET) Subject: [pypy-svn] r72762 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324211725.41FC2282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:17:23 2010 New Revision: 72762 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Also in the last commit (pressed Return to early): Added correct dealloc functions for our type objects. In this commit: Removed prints. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Wed Mar 24 22:17:23 2010 @@ -215,7 +215,6 @@ w_type = space.type(self) assert isinstance(w_type, W_PyCTypeObject) pto = w_type.pto - print "Called W_PyCObject.__del__" generic_cpy_call(space, pto.c_tp_dealloc, self) @@ -234,7 +233,6 @@ @cpython_api([PyObject], lltype.Void, external=False) def type_dealloc(space, obj): - print "type_dealloc of", obj obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) # type_dealloc code follows: @@ -259,9 +257,8 @@ callable = PyObject_dealloc pto.c_tp_dealloc = llhelper(callable.api_func.functype, make_wrapper(space, callable)) - print "Chose dealloc strategy %r for %r" % (callable.func, w_type) - callable = PyObject_Del pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE + callable = PyObject_Del pto.c_tp_free = llhelper(callable.api_func.functype, make_wrapper(space, callable)) pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) From arigo at codespeak.net Wed Mar 24 22:22:14 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 22:22:14 +0100 (CET) Subject: [pypy-svn] r72763 - pypy/branch/fix-64/pypy/lib Message-ID: <20100324212214.1D7F5282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 22:22:13 2010 New Revision: 72763 Modified: pypy/branch/fix-64/pypy/lib/resource.py Log: Fix. Alternatively, this should use ctypes_config_cache a bit more. Modified: pypy/branch/fix-64/pypy/lib/resource.py ============================================================================== --- pypy/branch/fix-64/pypy/lib/resource.py (original) +++ pypy/branch/fix-64/pypy/lib/resource.py Wed Mar 24 22:22:13 2010 @@ -28,8 +28,8 @@ class timeval(Structure): _fields_ = ( - ("tv_sec", c_int), - ("tv_usec", c_int), + ("tv_sec", c_long), + ("tv_usec", c_long), ) def __str__(self): return "(%s, %s)" % (self.tv_sec, self.tv_usec) From arigo at codespeak.net Wed Mar 24 22:27:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 22:27:09 +0100 (CET) Subject: [pypy-svn] r72764 - pypy/branch/fix-64/pypy/rpython/tool Message-ID: <20100324212709.C0F67282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 22:27:08 2010 New Revision: 72764 Modified: pypy/branch/fix-64/pypy/rpython/tool/rfficache.py Log: Fixes: a missing #include, and using %d to print a sizeof(). Modified: pypy/branch/fix-64/pypy/rpython/tool/rfficache.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/rfficache.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/rfficache.py Wed Mar 24 22:27:08 2010 @@ -13,7 +13,7 @@ from pypy.tool.gcc_cache import build_executable_cache def ask_gcc(question, add_source=""): - includes = ['stdlib.h', 'sys/types.h'] + includes = ['stdlib.h', 'stdio.h', 'sys/types.h'] include_string = "\n".join(["#include <%s>" % i for i in includes]) c_source = py.code.Source(''' // includes @@ -34,8 +34,8 @@ return build_executable_cache([c_file], eci) def sizeof_c_type(c_typename, **kwds): - question = 'printf("sizeof %s=%%d", sizeof(%s));' % (c_typename, - c_typename) + question = 'printf("sizeof %s=%%ld", (long)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]) From arigo at codespeak.net Wed Mar 24 22:42:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Mar 2010 22:42:11 +0100 (CET) Subject: [pypy-svn] r72765 - in pypy/branch/fix-64/pypy: interpreter interpreter/test module/posix Message-ID: <20100324214211.5EF2F282BDC@codespeak.net> Author: arigo Date: Wed Mar 24 22:42:09 2010 New Revision: 72765 Modified: pypy/branch/fix-64/pypy/interpreter/baseobjspace.py pypy/branch/fix-64/pypy/interpreter/gateway.py pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py pypy/branch/fix-64/pypy/module/posix/interp_posix.py Log: Partially undo a change: getting unsigned integers in RPython here looks a bit like too big a change, and there is really no reason to allow a value larger than 2**31 as far as I can tell. So for now, we just allow values between 0 and 2**31 as a regular int. Modified: pypy/branch/fix-64/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/fix-64/pypy/interpreter/baseobjspace.py Wed Mar 24 22:42:09 2010 @@ -1116,6 +1116,19 @@ self.wrap("expected an unsigned 32-bit integer")) return value + def c_nonnegint_w(self, w_obj): + # Like space.int_w(), but raises an app-level ValueError if + # the integer is negative or does not fit in 32 bits. 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")) + if value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit integer")) + return value + def warn(self, msg, w_warningcls): self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): import warnings Modified: pypy/branch/fix-64/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/gateway.py (original) +++ pypy/branch/fix-64/pypy/interpreter/gateway.py Wed Mar 24 22:42:09 2010 @@ -132,6 +132,9 @@ def visit_c_uint(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_c_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() @@ -242,6 +245,9 @@ def visit_c_uint(self, typ): self.run_args.append("space.c_uint_w(%s)" % (self.scopenext(),)) + def visit_c_nonnegint(self, typ): + self.run_args.append("space.c_nonnegint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -366,6 +372,9 @@ def visit_c_uint(self, typ): self.unwrap.append("space.c_uint_w(%s)" % (self.nextarg(),)) + def visit_c_nonnegint(self, typ): + self.unwrap.append("space.c_nonnegint_w(%s)" % (self.nextarg(),)) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) Modified: pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/fix-64/pypy/interpreter/test/test_gateway.py Wed Mar 24 22:42:09 2010 @@ -207,9 +207,12 @@ 'c_int']) app_ug = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, 'c_uint']) + app_ng = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_nonnegint']) assert app_ug is not app_g w_app_g = space.wrap(app_g) w_app_ug = space.wrap(app_ug) + w_app_ng = space.wrap(app_ng) # assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), space.wrap(13)) @@ -230,6 +233,14 @@ space.raises_w(space.w_OverflowError, space.call_function, w_app_ug, space.wrap(r_longlong(0x100000000))) + # + assert self.space.eq_w(space.call_function(w_app_ng, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ng, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ng, space.wrap(-1)) def test_interp2app_unwrap_spec_args_w(self): space = self.space Modified: pypy/branch/fix-64/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/branch/fix-64/pypy/module/posix/interp_posix.py (original) +++ pypy/branch/fix-64/pypy/module/posix/interp_posix.py Wed Mar 24 22:42:09 2010 @@ -649,7 +649,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setuid.unwrap_spec = [ObjSpace, "c_uint"] +setuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def seteuid(space, arg): """ seteuid(uid) @@ -661,7 +661,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -seteuid.unwrap_spec = [ObjSpace, "c_uint"] +seteuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setgid(space, arg): """ setgid(gid) @@ -673,7 +673,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setgid.unwrap_spec = [ObjSpace, "c_uint"] +setgid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setegid(space, arg): """ setegid(gid) @@ -685,7 +685,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setegid.unwrap_spec = [ObjSpace, "c_uint"] +setegid.unwrap_spec = [ObjSpace, "c_nonnegint"] def chroot(space, path): """ chroot(path) @@ -785,7 +785,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setreuid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] +setreuid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def setregid(space, rgid, egid): """ setregid(rgid, egid) @@ -797,7 +797,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setregid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] +setregid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def getsid(space, pid): """ getsid(pid) -> sid @@ -866,7 +866,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -chown.unwrap_spec = [ObjSpace, str, "c_uint", "c_uint"] +chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"] if _WIN: from pypy.rlib import rwin32 From xoraxax at codespeak.net Wed Mar 24 22:53:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 22:53:03 +0100 (CET) Subject: [pypy-svn] r72767 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include Message-ID: <20100324215303.939B3282BDC@codespeak.net> Author: xoraxax Date: Wed Mar 24 22:53:01 2010 New Revision: 72767 Removed: pypy/branch/cpython-extension/pypy/module/cpyext/include/macros.h Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h pypy/branch/cpython-extension/pypy/module/cpyext/include/dictobject.h pypy/branch/cpython-extension/pypy/module/cpyext/include/floatobject.h pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h pypy/branch/cpython-extension/pypy/module/cpyext/include/pythonrun.h pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h Log: Generate function declarations for C API functions written in Python code. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Wed Mar 24 22:53:01 2010 @@ -1,4 +1,3 @@ - - Generate header files programmatically. - Implement C API. - Complete the PyTypeObject initialization code. - properly support "borrowed" references: the PyObject must be stored Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 22:53:01 2010 @@ -42,6 +42,7 @@ """.split() for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) +udir.join('pypy_decl.h').write("/* Will be filled later */") globals().update(rffi_platform.configure(CConfig_constants)) _NOT_SPECIFIED = object() @@ -321,6 +322,7 @@ pypy_rename_h = udir.join('pypy_rename.h') pypy_rename_h.write('\n'.join(pypy_rename)) + configure() # needs pypy_rename.h # Structure declaration code @@ -337,9 +339,10 @@ struct PyPyAPI* pypyAPI = &_pypyAPI; """ % dict(members=structmembers) - # implement function callbacks + # implement function callbacks and generate function decls functions = [] - for name, func in FUNCTIONS.iteritems(): + pypy_decls = [] + for name, func in sorted(FUNCTIONS.iteritems()): restype = db.gettype(func.restype).replace('@', '') args = [] for i, argtype in enumerate(func.argtypes): @@ -349,9 +352,13 @@ args = ', '.join(args) callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) header = "%s %s(%s)" % (restype, name, args) + pypy_decls.append(header + ";") body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) + pypy_decl_h = udir.join('pypy_decl.h') + pypy_decl_h.write('\n'.join(pypy_decls)) + global_objects = [] for name, (type, expr) in GLOBALS.iteritems(): global_objects.append('%s %s = NULL;' % (type, name.replace("#", ""))) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Wed Mar 24 22:53:01 2010 @@ -37,6 +37,7 @@ #include "descrobject.h" #include "tupleobject.h" #include "dictobject.h" -#include "macros.h" + +#include #endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h Wed Mar 24 22:53:01 2010 @@ -14,9 +14,6 @@ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False -int PyBool_Check(PyObject*); -PyObject* PyBool_FromLong(long); - #ifdef __cplusplus } #endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/dictobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/dictobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/dictobject.h Wed Mar 24 22:53:01 2010 @@ -7,8 +7,6 @@ extern "C" { #endif -PyObject * PyDict_New(void); -int PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/floatobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/floatobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/floatobject.h Wed Mar 24 22:53:01 2010 @@ -7,8 +7,6 @@ extern "C" { #endif -PyObject* PyFloat_FromDouble(double); -double PyFloat_AsDouble(PyObject*); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h Wed Mar 24 22:53:01 2010 @@ -10,10 +10,6 @@ #define PYTHON_API_VERSION 1013 #define PYTHON_API_STRING "1013" -PyObject *Py_InitModule4(const char* name, PyMethodDef* methods, - const char *doc, PyObject *self, - int apiver); - #define Py_InitModule(name, methods) \ Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \ PYTHON_API_VERSION) @@ -22,7 +18,6 @@ Py_InitModule4(name, methods, doc, (PyObject *)NULL, \ PYTHON_API_VERSION) -PyObject * PyModule_GetDict(PyObject *); #ifdef __cplusplus Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 24 22:53:01 2010 @@ -377,26 +377,18 @@ PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; +// defined in typeobject.c int PyType_Ready(PyTypeObject *); /* objimpl.h ----------------------------------------------*/ -PyObject * _PyObject_New(PyObject *); -// PyVarObject * _PyObject_NewVar(PyTypeObject *, Py_ssize_t); - #define PyObject_New(type, typeobj) \ ( (type *) _PyObject_New(typeobj) ) #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) -void PyObject_Del(void *); /* PyPy internal ----------------------------------- */ int PyPyType_Register(PyTypeObject *); -int PyObject_IsTrue(PyObject *); -int PyObject_Not(PyObject *); -int PyObject_HasAttr(PyObject *, PyObject *); -int PyObject_SetAttr(PyObject *, PyObject *, PyObject *); - #endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Wed Mar 24 22:53:01 2010 @@ -8,9 +8,6 @@ #endif PyAPI_DATA(PyObject *) PyExc_Exception; -void PyErr_SetString(PyObject *, char *); -PyObject * PyErr_Occurred(void); -void PyErr_Clear(); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pythonrun.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pythonrun.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pythonrun.h Wed Mar 24 22:53:01 2010 @@ -6,7 +6,6 @@ extern "C" { #endif -int Py_IsInitialized(void); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h Wed Mar 24 22:53:01 2010 @@ -7,9 +7,6 @@ extern "C" { #endif -PyObject * PyString_FromStringAndSize(const char *, Py_ssize_t); -PyObject * PyString_FromString(const char *); -Py_ssize_t PyString_Size(PyObject *); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/tupleobject.h Wed Mar 24 22:53:01 2010 @@ -7,10 +7,8 @@ extern "C" { #endif -PyObject * PyTuple_New(Py_ssize_t size); +/* defined in varargswrapper.c */ PyObject * PyTuple_Pack(Py_ssize_t, ...); -PyObject * PyTuple_GetItem(PyObject *, Py_ssize_t); -int PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); #ifdef __cplusplus } From afa at codespeak.net Wed Mar 24 23:11:09 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 23:11:09 +0100 (CET) Subject: [pypy-svn] r72769 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324221109.7FA9B282BDC@codespeak.net> Author: afa Date: Wed Mar 24 23:11:07 2010 New Revision: 72769 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: compatibility with CPython 2.4 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 23:11:07 2010 @@ -94,15 +94,16 @@ arg = from_ref(space, arg) newargs.append(arg) try: - return func(space, *newargs) - except OperationError, e: - if not hasattr(api_function, "error_value"): - raise - state = space.fromcache(State) - e.normalize_exception(space) - state.exc_type = e.w_type - state.exc_value = e.get_w_value(space) - return api_function.error_value + try: + return func(space, *newargs) + except OperationError, e: + if not hasattr(api_function, "error_value"): + raise + state = space.fromcache(State) + e.normalize_exception(space) + state.exc_type = e.w_type + state.exc_value = e.get_w_value(space) + return api_function.error_value finally: from pypy.module.cpyext.macros import Py_DECREF for arg in to_decref: From afa at codespeak.net Wed Mar 24 23:29:17 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 23:29:17 +0100 (CET) Subject: [pypy-svn] r72772 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324222917.430BC282BE2@codespeak.net> Author: afa Date: Wed Mar 24 23:29:15 2010 New Revision: 72772 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Add *all* functions to the exported symbols, even when not renamed Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 23:29:15 2010 @@ -310,6 +310,7 @@ if rename: for name in export_symbols: if name.startswith("PyPy"): + renamed_symbols.append(name) continue if "#" in name: deref = "*" From afa at codespeak.net Wed Mar 24 23:33:21 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 24 Mar 2010 23:33:21 +0100 (CET) Subject: [pypy-svn] r72774 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324223321.1729C282BE2@codespeak.net> Author: afa Date: Wed Mar 24 23:33:19 2010 New Revision: 72774 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Another 2.4 compatibility issue Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 23:33:19 2010 @@ -16,6 +16,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, unwrap_spec +# CPython 2.4 compatibility +from py.builtin import BaseException Py_ssize_t = lltype.Signed From xoraxax at codespeak.net Wed Mar 24 23:42:05 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 23:42:05 +0100 (CET) Subject: [pypy-svn] r72775 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100324224205.6013A282BE2@codespeak.net> Author: xoraxax Date: Wed Mar 24 23:42:03 2010 New Revision: 72775 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Const hack shouldnt be necessary anymore. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 24 23:42:03 2010 @@ -303,7 +303,6 @@ structindex = {} prologue = """\ - #define const /* cheat */ #include #include """ From xoraxax at codespeak.net Wed Mar 24 23:42:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 24 Mar 2010 23:42:13 +0100 (CET) Subject: [pypy-svn] r72776 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100324224213.AEDE7282BE2@codespeak.net> Author: xoraxax Date: Wed Mar 24 23:42:12 2010 New Revision: 72776 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Log: Fix test. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Wed Mar 24 23:42:12 2010 @@ -5,7 +5,5 @@ class TestTupleObject(BaseApiTest): def test_tupleobject(self, space, api): assert not api.PyTuple_Check(space.w_None) - py.test.raises(TypeError, api.PyTuple_SetItem, space.w_None, - 0, space.w_None) - api.PyTuple_SetItem(space.w_None, 0, space.w_None) - #api.PyErr_Clear() + assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1 + api.PyErr_Clear() From xoraxax at codespeak.net Thu Mar 25 01:51:46 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 01:51:46 +0100 (CET) Subject: [pypy-svn] r72777 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325005146.BF454282BE2@codespeak.net> Author: xoraxax Date: Thu Mar 25 01:51:44 2010 New Revision: 72777 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Added also another check. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Thu Mar 25 01:51:44 2010 @@ -18,13 +18,15 @@ def PyTuple_SetItem(space, w_t, pos, w_obj): if not PyTuple_Check(space, w_t): PyErr_BadInternalCall(space) - assert isinstance(w_t, W_TupleObject) # XXX add check here + assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj Py_DECREF(space, w_obj) # SetItem steals a reference! XXX this needs to go into the wrapper return 0 @cpython_api([PyObject, Py_ssize_t], PyObject) def PyTuple_GetItem(space, w_t, pos): - assert isinstance(w_t, W_TupleObject) # XXX add check here + if not PyTuple_Check(space, w_t): + PyErr_BadInternalCall(space) + assert isinstance(w_t, W_TupleObject) w_obj = w_t.wrappeditems[pos] return w_obj From xoraxax at codespeak.net Thu Mar 25 01:52:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 01:52:03 +0100 (CET) Subject: [pypy-svn] r72778 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325005203.852A1282BE2@codespeak.net> Author: xoraxax Date: Thu Mar 25 01:52:01 2010 New Revision: 72778 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Refactored memory management, now we should have less issues. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 01:52:01 2010 @@ -68,6 +68,13 @@ self.argnames = argnames[1:] assert len(self.argnames) == len(self.argtypes) + def get_llhelper(self, space): + llh = getattr(self, '_llhelper', None) + if llh is None: + llh = llhelper(self.functype, make_wrapper(space, self.callable)) + self._llhelper = llh + return llh + def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True): if error is _NOT_SPECIFIED: if restype is PyObject: @@ -143,7 +150,7 @@ 'Py_False': ('PyObject*', 'space.w_False'), 'PyExc_Exception': ('PyObject*', 'space.w_Exception'), 'PyExc_TypeError': ('PyObject*', 'space.w_TypeError'), - 'PyType_Type': ('PyTypeObject*', 'space.w_type'), + 'PyType_Type#': ('PyTypeObject*', 'space.w_type'), 'PyBaseObject_Type#': ('PyTypeObject*', 'space.w_object'), } @@ -400,6 +407,10 @@ ptr = ctypes.c_void_p.in_dll(bridge, name) ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), ctypes.c_void_p).value + # hack, init base of the type type + if name == "PyType_Type": + pto = rffi.cast(PyTypeObjectPtr, ptr) + pto.c_tp_base = make_ref(space, w_object) # implement structure initialization code for name, func in FUNCTIONS.iteritems(): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Thu Mar 25 01:52:01 2010 @@ -130,7 +130,7 @@ self.w_import_module = self.space.wrap(self.import_module) self.w_import_extension = self.space.wrap(self.import_extension) self.w_check_refcnts = self.space.wrap(self.check_refcnts) - #self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!") + self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!") #self.space.fromcache(State).print_refcounts() def teardown_method(self, func): @@ -143,7 +143,7 @@ except OperationError: pass self.space.fromcache(State).print_refcounts() - #self.check_refcnts("Test leaks object: %r") + self.check_refcnts("Test leaks object: %r") def check_refcnts(self, message): # check for sane refcnts Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 01:52:01 2010 @@ -9,14 +9,14 @@ from pypy.objspace.std.typeobject import W_TypeObject from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct -from pypy.module.cpyext.api import PyObject, PyVarObjectFields, Py_ssize_t -from pypy.module.cpyext.api import Py_TPFLAGS_READYING, Py_TPFLAGS_READY -from pypy.module.cpyext.api import make_wrapper, Py_TPFLAGS_HEAPTYPE +from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ + PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ + Py_TPFLAGS_READY, make_wrapper, Py_TPFLAGS_HEAPTYPE, make_ref from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State from pypy.module.cpyext.methodobject import generic_cpy_call +from pypy.module.cpyext.macros import Py_DECREF PyTypeObject = lltype.ForwardReference() @@ -209,25 +209,30 @@ def __init__(self, space): self.space = space - def __del__(self): - space = self.space - self.clear_all_weakrefs() - w_type = space.type(self) - assert isinstance(w_type, W_PyCTypeObject) - pto = w_type.pto - generic_cpy_call(space, pto.c_tp_dealloc, self) +# def __del__(self): +# space = self.space +# self.clear_all_weakrefs() +# w_type = space.type(self) +# assert isinstance(w_type, W_PyCTypeObject) +# pto = w_type.pto +# generic_cpy_call(space, pto.c_tp_dealloc, self) @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): + print "Dealloc of", obj pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto - #basedealloc = pto.c_tp_dealloc - # XXX lookup basedealloc which is not subtype_dealloc + this_func_ptr = subtype_dealloc.api_func.get_llhelper(space) + ref_of_object_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_object)) + while base.c_tp_dealloc == this_func_ptr: + base = base.c_tp_base + assert base + dealloc = base.c_tp_dealloc # XXX call tp_del if necessary - # XXX call basedealloc instead of a fixed type_dealloc - type_dealloc(space, obj) + generic_cpy_call(space, dealloc, obj) + pto = rffi.cast(PyObject, pto) Py_DECREF(space, pto) @@ -240,29 +245,32 @@ # tp_subclasses # free tp_doc lltype.free(obj_pto.c_tp_name, flavor="raw") - generic_cpy_call(space, type_pto.c_tp_free, obj) - - + obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) + generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) def allocate_type_obj(space, w_type): """ Allocates a pto from a w_type which must be a PyPy type. """ from pypy.module.cpyext.object import PyObject_dealloc, PyObject_Del assert not isinstance(w_type, W_PyCTypeObject) + assert isinstance(w_type, W_TypeObject) pto = lltype.malloc(PyTypeObject, None, flavor="raw") - if space.is_w(w_type, space.w_type): - callable = subtype_dealloc - pto.c_tp_dealloc = llhelper(callable.api_func.functype, - make_wrapper(space, callable)) + if space.is_w(w_type, space.w_object): + pto.c_tp_dealloc = PyObject_dealloc.api_func.get_llhelper(space) + elif space.is_w(w_type, space.w_type): + pto.c_tp_dealloc = type_dealloc.api_func.get_llhelper(space) else: - callable = PyObject_dealloc - pto.c_tp_dealloc = llhelper(callable.api_func.functype, - make_wrapper(space, callable)) + pto.c_tp_dealloc = subtype_dealloc.api_func.get_llhelper(space) pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE - callable = PyObject_Del - pto.c_tp_free = llhelper(callable.api_func.functype, - make_wrapper(space, callable)) + pto.c_tp_free = PyObject_Del.api_func.get_llhelper(space) pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out + bases_w = w_type.bases_w + assert len(bases_w) <= 1 + if not bases_w: + pto.c_tp_base = lltype.nullptr(PyTypeObject) + elif not space.is_w(w_type, space.w_type): # avoid endless recursion + ref = make_ref(space, bases_w[0]) + pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref) # XXX fill slots in pto return pto From afa at codespeak.net Thu Mar 25 02:23:13 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 25 Mar 2010 02:23:13 +0100 (CET) Subject: [pypy-svn] r72779 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325012313.114F4282BE2@codespeak.net> Author: afa Date: Thu Mar 25 02:23:11 2010 New Revision: 72779 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Add some notes, to implement... Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 02:23:11 2010 @@ -50,6 +50,25 @@ _NOT_SPECIFIED = object() CANNOT_FAIL = object() +# The same function can be called in three different contexts: +# (1) from C code +# (2) in the test suite, though the "api" object +# (3) from RPython code, for example in the implementation of another function. +# +# In contexts (2) and (3), a function declaring a PyObject argument type will +# receive a wrapped pypy object if the parameter name starts with 'w_', a +# reference (= rffi pointer) otherwise; conversion is automatic. Context (2) +# only allows calls with a wrapped object. +# +# Functions with a PyObject return type should return a wrapped object. +# +# Functions may raise exceptions. In context (3), the exception flows normally +# through the calling function. In context (1) and (2), the exception is +# caught; if it is an OperationError, it is stored in the thread state; other +# exceptions generate a OperationError(w_SystemError). In every case the +# funtion returns the error value specifed in the API. +# + class ApiFunction: def __init__(self, argtypes, restype, callable, borrowed, error): self.argtypes = argtypes From fijal at codespeak.net Thu Mar 25 04:48:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 04:48:06 +0100 (CET) Subject: [pypy-svn] r72780 - pypy/branch/jit-profiling Message-ID: <20100325034806.5ED4E282BE2@codespeak.net> Author: fijal Date: Thu Mar 25 04:48:03 2010 New Revision: 72780 Removed: pypy/branch/jit-profiling/ Log: Kill this branch. The approach didn't work out, we need to think out the whole idea again. From fijal at codespeak.net Thu Mar 25 04:50:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 04:50:53 +0100 (CET) Subject: [pypy-svn] r72781 - pypy/branch/judy-trees Message-ID: <20100325035053.7DE01282BE2@codespeak.net> Author: fijal Date: Thu Mar 25 04:50:52 2010 New Revision: 72781 Removed: pypy/branch/judy-trees/ Log: Kill this branch. Zooko started working on it but gave up and I don't think this approach is worth anything From afa at codespeak.net Thu Mar 25 10:03:14 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 25 Mar 2010 10:03:14 +0100 (CET) Subject: [pypy-svn] r72782 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325090314.3247F282BE2@codespeak.net> Author: afa Date: Thu Mar 25 10:03:12 2010 New Revision: 72782 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: use helper function Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 10:03:12 2010 @@ -434,8 +434,7 @@ # implement structure initialization code for name, func in FUNCTIONS.iteritems(): pypyAPI[structindex[name]] = ctypes.cast( - ll2ctypes.lltype2ctypes(llhelper(func.functype, - make_wrapper(space, func.callable))), + ll2ctypes.lltype2ctypes(func.get_llhelper(space)), ctypes.c_void_p) return modulename.new(ext='') From jandem at codespeak.net Thu Mar 25 10:38:46 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Thu, 25 Mar 2010 10:38:46 +0100 (CET) Subject: [pypy-svn] r72783 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100325093846.3DF37282BE2@codespeak.net> Author: jandem Date: Thu Mar 25 10:38:44 2010 New Revision: 72783 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Log: Test I want to pass Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 10:38:44 2010 @@ -39,3 +39,21 @@ assert module.get_hello2() == 'Hello world' assert module.test_Size() raises(TypeError, module.test_Size_exception) + + def test_string_buffer_init(self): + skip('In progress') + module = self.import_extension('foo', [ + ("getstring", "METH_NOARGS", + """ + PyObject* s = PyString_FromStringAndSize(NULL, 3); + char* c = PyString_AsString(s); + Py_ssize_t len = PyString_Size(s); + c[0] = 'a'; + c[1] = 'b'; + c[len-1] = 'c'; + return s; + """), + ]) + s = module.getstring() + assert len(s) == 3 + assert s == 'abc' From arigo at codespeak.net Thu Mar 25 11:50:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 11:50:17 +0100 (CET) Subject: [pypy-svn] r72787 - pypy/trunk/pypy/doc/config Message-ID: <20100325105017.F00AF282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 11:50:16 2010 New Revision: 72787 Removed: pypy/trunk/pypy/doc/config/objspace.usemodules.cpyext.txt Log: Remove it from here too. From arigo at codespeak.net Thu Mar 25 12:01:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 12:01:08 +0100 (CET) Subject: [pypy-svn] r72788 - in pypy/trunk/pypy: module/_socket/test rlib Message-ID: <20100325110108.7554E282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 12:01:06 2010 New Revision: 72788 Modified: pypy/trunk/pypy/module/_socket/test/test_sock_app.py pypy/trunk/pypy/rlib/rsocket.py Log: Fix (shown by test_NtoH in test_sock_app.py). 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 Thu Mar 25 12:01:06 2010 @@ -108,6 +108,9 @@ w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.ntohl(x)") assert space.unwrap(w_n) == socket.ntohl(125) + w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], + "(_socket, x): return _socket.ntohl(x)") + assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) def test_htons(): w_n = space.appexec([w_socket, space.wrap(125)], @@ -118,6 +121,9 @@ w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.htonl(x)") assert space.unwrap(w_n) == socket.htonl(125) + w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], + "(_socket, x): return _socket.htonl(x)") + assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) def test_aton_ntoa(): ip = '123.45.67.89' Modified: pypy/trunk/pypy/rlib/rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/rsocket.py (original) +++ pypy/trunk/pypy/rlib/rsocket.py Thu Mar 25 12:01:06 2010 @@ -42,13 +42,15 @@ return rffi.cast(lltype.Signed, _c.ntohs(x)) def ntohl(x): - return rffi.cast(lltype.Signed, _c.ntohl(x)) + # accepts and returns an Unsigned + return rffi.cast(lltype.Unsigned, _c.ntohl(x)) def htons(x): return rffi.cast(lltype.Signed, _c.htons(x)) def htonl(x): - return rffi.cast(lltype.Signed, _c.htonl(x)) + # accepts and returns an Unsigned + return rffi.cast(lltype.Unsigned, _c.htonl(x)) _FAMILIES = {} From arigo at codespeak.net Thu Mar 25 12:19:51 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 12:19:51 +0100 (CET) Subject: [pypy-svn] r72789 - in pypy/trunk/pypy: interpreter interpreter/test module/posix Message-ID: <20100325111951.BC14A282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 12:19:37 2010 New Revision: 72789 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/test/test_gateway.py pypy/trunk/pypy/module/posix/interp_posix.py Log: Merge r72765 from the fix-64 branch. It's needed because trunk does not translate right now :-( Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Thu Mar 25 12:19:37 2010 @@ -1116,6 +1116,19 @@ self.wrap("expected an unsigned 32-bit integer")) return value + def c_nonnegint_w(self, w_obj): + # Like space.int_w(), but raises an app-level ValueError if + # the integer is negative or does not fit in 32 bits. 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")) + if value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit 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 Thu Mar 25 12:19:37 2010 @@ -132,6 +132,9 @@ def visit_c_uint(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_c_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() @@ -242,6 +245,9 @@ def visit_c_uint(self, typ): self.run_args.append("space.c_uint_w(%s)" % (self.scopenext(),)) + def visit_c_nonnegint(self, typ): + self.run_args.append("space.c_nonnegint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -366,6 +372,9 @@ def visit_c_uint(self, typ): self.unwrap.append("space.c_uint_w(%s)" % (self.nextarg(),)) + def visit_c_nonnegint(self, typ): + self.unwrap.append("space.c_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 Thu Mar 25 12:19:37 2010 @@ -207,9 +207,12 @@ 'c_int']) app_ug = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, 'c_uint']) + app_ng = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_nonnegint']) assert app_ug is not app_g w_app_g = space.wrap(app_g) w_app_ug = space.wrap(app_ug) + w_app_ng = space.wrap(app_ng) # assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), space.wrap(13)) @@ -230,6 +233,14 @@ space.raises_w(space.w_OverflowError, space.call_function, w_app_ug, space.wrap(r_longlong(0x100000000))) + # + assert self.space.eq_w(space.call_function(w_app_ng, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ng, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ng, space.wrap(-1)) def test_interp2app_unwrap_spec_args_w(self): space = self.space Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Thu Mar 25 12:19:37 2010 @@ -649,7 +649,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setuid.unwrap_spec = [ObjSpace, "c_uint"] +setuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def seteuid(space, arg): """ seteuid(uid) @@ -661,7 +661,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -seteuid.unwrap_spec = [ObjSpace, "c_uint"] +seteuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setgid(space, arg): """ setgid(gid) @@ -673,7 +673,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setgid.unwrap_spec = [ObjSpace, "c_uint"] +setgid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setegid(space, arg): """ setegid(gid) @@ -685,7 +685,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setegid.unwrap_spec = [ObjSpace, "c_uint"] +setegid.unwrap_spec = [ObjSpace, "c_nonnegint"] def chroot(space, path): """ chroot(path) @@ -785,7 +785,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setreuid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] +setreuid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def setregid(space, rgid, egid): """ setregid(rgid, egid) @@ -797,7 +797,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setregid.unwrap_spec = [ObjSpace, "c_uint", "c_uint"] +setregid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def getsid(space, pid): """ getsid(pid) -> sid @@ -866,7 +866,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -chown.unwrap_spec = [ObjSpace, str, "c_uint", "c_uint"] +chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"] if _WIN: from pypy.rlib import rwin32 From arigo at codespeak.net Thu Mar 25 12:29:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 12:29:31 +0100 (CET) Subject: [pypy-svn] r72790 - pypy/trunk/pypy/doc Message-ID: <20100325112931.9F4E4282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 12:29:29 2010 New Revision: 72790 Modified: pypy/trunk/pypy/doc/coding-guide.txt Log: Clarification. Modified: pypy/trunk/pypy/doc/coding-guide.txt ============================================================================== --- pypy/trunk/pypy/doc/coding-guide.txt (original) +++ pypy/trunk/pypy/doc/coding-guide.txt Thu Mar 25 12:29:29 2010 @@ -241,11 +241,17 @@ We are using -**integer, float, string, boolean** +**integer, float, boolean** - a lot of, but not all string methods are supported. When slicing a string - it is necessary to prove that the slice start and stop indexes are - non-negative. + works. + +**strings** + + a lot of, but not all string methods are supported. Indexes can be + negative. In case they are not, then you get slightly more efficient + code if the translator can prove that they are non-negative. When + slicing a string it is necessary to prove that the slice start and + stop indexes are non-negative. **tuples** From arigo at codespeak.net Thu Mar 25 13:42:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 13:42:40 +0100 (CET) Subject: [pypy-svn] r72796 - in pypy/branch/fix-64/pypy/translator/c: . test Message-ID: <20100325124240.3C46A282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 13:42:39 2010 New Revision: 72796 Modified: pypy/branch/fix-64/pypy/translator/c/genc.py pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py pypy/branch/fix-64/pypy/translator/c/test/test_typed.py Log: Add a failing test. Modified: pypy/branch/fix-64/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/genc.py (original) +++ pypy/branch/fix-64/pypy/translator/c/genc.py Thu Mar 25 13:42:39 2010 @@ -167,16 +167,19 @@ have___thread = None + def merge_eci(self, *ecis): + self.eci = self.eci.merge(*ecis) + def collect_compilation_info(self, db): # we need a concrete gcpolicy to do this - self.eci = self.eci.merge(db.gcpolicy.compilation_info()) + self.merge_eci(db.gcpolicy.compilation_info()) all = [] for node in self.db.globalcontainers(): eci = getattr(node, 'compilation_info', None) if eci: all.append(eci) - self.eci = self.eci.merge(*all) + self.merge_eci(*all) def get_gcpolicyclass(self): if self.gcpolicy is None: Modified: pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py Thu Mar 25 13:42:39 2010 @@ -782,3 +782,47 @@ fn = self.getcompiled(f, []) res = fn() assert res == 42 + + def test_padding_in_prebuilt_struct(self): + from pypy.rpython.lltypesystem import rffi + from pypy.rpython.tool import rffi_platform + eci = rffi_platform.eci_from_header(""" + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + char c2; /* followed by 3 bytes of padding */ + int i2; + char c3; /* followed by 3 or 7 bytes of padding */ + long l3; + char c4; + } foobar_t; + """) + class CConfig: + _compilation_info_ = eci + STRUCT = rffi_platform.Struct("foobar_t", + [("c1", Signed), + ("s1", Signed), + ("l3", Signed)]) + S = rffi_platform.configure(CConfig)['STRUCT'] + s1 = malloc(S, immortal=True) + s1.c_c1 = rffi.cast(S.c_c1, -12) + s1.c_s1 = rffi.cast(S.c_s1, -7843) + s1.c_l3 = -98765432 + s2 = malloc(S, immortal=True) + s2.c_c1 = rffi.cast(S.c_c1, -123) + s2.c_s1 = rffi.cast(S.c_s1, -789) + s2.c_l3 = -9999999 + # + def f(n): + if n > 5: + s = s1 + else: + s = s2 + return s.c_l3 + # + self.include_also_eci = eci + fn = self.getcompiled(f, [int]) + res = fn(10) + assert res == -98765432 + res = fn(1) + assert res == -9999999 Modified: pypy/branch/fix-64/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_typed.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_typed.py Thu Mar 25 13:42:39 2010 @@ -28,6 +28,8 @@ def compilefunc(self, t, func): from pypy.translator.c import genc self.builder = builder = genc.CExtModuleBuilder(t, func, config=t.config) + if hasattr(self, 'include_also_eci'): + builder.merge_eci(self.include_also_eci) builder.generate_source() builder.compile() return builder.get_entry_point() From xoraxax at codespeak.net Thu Mar 25 14:02:06 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 14:02:06 +0100 (CET) Subject: [pypy-svn] r72798 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325130206.5227F282BE5@codespeak.net> Author: xoraxax Date: Thu Mar 25 14:02:04 2010 New Revision: 72798 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Implement refcount checking for our tests. Only one test is failing, amaury may fix it :-) Refcounts are now checked against the baseline after every test is run. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 14:02:04 2010 @@ -208,7 +208,7 @@ hints["padding"] = hints["padding"] + tuple(pad_fields) return lltype.Struct(hints["c_name"], hints=hints, *new_fields) -def make_ref(space, w_obj, borrowed=False): +def make_ref(space, w_obj, borrowed=False, steal=False): if w_obj is None: return lltype.nullptr(PyObject.TO) assert isinstance(w_obj, W_Root) @@ -242,7 +242,7 @@ py_obj = rffi.cast(PyObject, py_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj - else: + elif not steal: py_obj.c_obj_refcnt += 1 # XXX borrowed references? return py_obj Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 14:02:04 2010 @@ -21,6 +21,10 @@ def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 + at cpython_api([PyObject], lltype.Void) +def Py_XDECREF(space, obj): + if obj: + Py_DECREF(space, obj) def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py Thu Mar 25 14:02:04 2010 @@ -44,4 +44,3 @@ assert module.get_false() == False assert module.test_FromLong() == True assert module.test_Check() == True - self.check_refcnts("FOOOOOO %r") Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Thu Mar 25 14:02:04 2010 @@ -69,6 +69,7 @@ class AppTestCpythonExtensionBase: def setup_class(cls): cls.space = gettestobjspace(usemodules=['cpyext']) + cls.freeze_refcnts() def import_module(self, name, init=None, body=''): if init is not None: @@ -129,9 +130,7 @@ def setup_method(self, func): self.w_import_module = self.space.wrap(self.import_module) self.w_import_extension = self.space.wrap(self.import_extension) - self.w_check_refcnts = self.space.wrap(self.check_refcnts) - self.check_refcnts("Object has refcnt != 1: %r -- Not executing test!") - #self.space.fromcache(State).print_refcounts() + #self.check_and_print_leaks("Object %r leaked some time ago (refcount %i) -- Not executing test!") def teardown_method(self, func): try: @@ -142,16 +141,31 @@ Py_DECREF(self.space, w_mod) except OperationError: pass - self.space.fromcache(State).print_refcounts() - self.check_refcnts("Test leaks object: %r") + if self.check_and_print_leaks(): + assert False, "Test leaks object(s)." - def check_refcnts(self, message): + @classmethod + def freeze_refcnts(cls): + state = cls.space.fromcache(State) + cls.frozen_refcounts = {} + for w_obj, obj in state.py_objects_w2r.iteritems(): + cls.frozen_refcounts[w_obj] = obj.c_obj_refcnt + + def check_and_print_leaks(self): # check for sane refcnts - for w_obj in (self.space.w_True, self.space.w_False, - self.space.w_None): - state = self.space.fromcache(State) - obj = state.py_objects_w2r.get(w_obj) - assert obj.c_obj_refcnt == 1, message % (w_obj, ) + leaking = False + state = self.space.fromcache(State) + global_objects_w = set() + for w_obj, obj in state.py_objects_w2r.iteritems(): + base_refcnt = self.frozen_refcounts.get(w_obj) + delta = obj.c_obj_refcnt + if base_refcnt is not None: + delta -= base_refcnt + if delta != 0: + leaking = True + print >>sys.stderr, "Leaking %r: %i references" % (w_obj, delta) + return leaking + class AppTestCpythonExtension(AppTestCpythonExtensionBase): def test_createmodule(self): @@ -324,7 +338,7 @@ refcnt_after = Py_REFCNT(true); Py_DECREF(true); Py_DECREF(true); - printf("REFCNT %i %i\\n", refcnt, refcnt_after); + fprintf(stderr, "REFCNT %i %i\\n", refcnt, refcnt_after); return PyBool_FromLong(refcnt_after == refcnt+2 && refcnt < 3); } static PyObject* foo_bar(PyObject* self, PyObject *args) @@ -339,8 +353,9 @@ if (PyTuple_SetItem(tup, 0, true) < 0) return NULL; refcnt_after = Py_REFCNT(true); - printf("REFCNT2 %i %i\\n", refcnt, refcnt_after); - return PyBool_FromLong(refcnt_after == refcnt && refcnt < 3); + Py_DECREF(tup); + fprintf(stderr, "REFCNT2 %i %i\\n", refcnt, refcnt_after); + return PyBool_FromLong(refcnt_after == refcnt); } static PyMethodDef methods[] = { Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 14:02:04 2010 @@ -16,7 +16,7 @@ from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State from pypy.module.cpyext.methodobject import generic_cpy_call -from pypy.module.cpyext.macros import Py_DECREF +from pypy.module.cpyext.macros import Py_DECREF, Py_XDECREF PyTypeObject = lltype.ForwardReference() @@ -225,7 +225,8 @@ assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto this_func_ptr = subtype_dealloc.api_func.get_llhelper(space) - ref_of_object_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_object)) + ref_of_object_type = rffi.cast(PyTypeObjectPtr, + make_ref(space, space.w_object, steal=True)) while base.c_tp_dealloc == this_func_ptr: base = base.c_tp_base assert base @@ -240,13 +241,16 @@ def type_dealloc(space, obj): obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + Py_XDECREF(space, obj_pto.c_tp_base) # type_dealloc code follows: - # XXX XDECREF tp_base, tp_dict, tp_bases, tp_mro, tp_cache, + # XXX XDECREF tp_dict, tp_bases, tp_mro, tp_cache, # tp_subclasses # free tp_doc lltype.free(obj_pto.c_tp_name, flavor="raw") obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) + pto = rffi.cast(PyObject, type_pto) + Py_DECREF(space, type_pto) def allocate_type_obj(space, w_type): """ Allocates a pto from a w_type which must be a PyPy type. """ From xoraxax at codespeak.net Thu Mar 25 14:46:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 14:46:03 +0100 (CET) Subject: [pypy-svn] r72802 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325134603.03B61282BE5@codespeak.net> Author: xoraxax Date: Thu Mar 25 14:46:01 2010 New Revision: 72802 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Add cast. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 14:46:01 2010 @@ -241,7 +241,8 @@ def type_dealloc(space, obj): obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) - Py_XDECREF(space, obj_pto.c_tp_base) + base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) + Py_XDECREF(space, base_pyo) # type_dealloc code follows: # XXX XDECREF tp_dict, tp_bases, tp_mro, tp_cache, # tp_subclasses From jandem at codespeak.net Thu Mar 25 14:59:49 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Thu, 25 Mar 2010 14:59:49 +0100 (CET) Subject: [pypy-svn] r72804 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100325135949.47026282BE5@codespeak.net> Author: jandem Date: Thu Mar 25 14:59:47 2010 New Revision: 72804 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Log: Implement amaury's string buffer proposal Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 14:59:47 2010 @@ -16,6 +16,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, unwrap_spec +from pypy.objspace.std.stringobject import W_StringObject # CPython 2.4 compatibility from py.builtin import BaseException @@ -182,6 +183,11 @@ PyVarObjectFields = PyObjectFields + (("obj_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) +PyStringObject = lltype.ForwardReference() +PyStringObjectPtr = lltype.Ptr(PyStringObject) +PyStringObjectFields = PyVarObjectFields + \ + (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) +cpython_struct("PyStringObject", PyStringObjectFields, PyStringObject) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): @@ -194,6 +200,13 @@ class InvalidPointerException(Exception): pass +def force_string(space, ref): + ref = rffi.cast(PyStringObjectPtr, ref) + s = rffi.charpsize2str(ref.c_buffer, ref.c_size) + w_str = space.wrap(s) + s_ptr = make_ref(space, w_str) + return w_str + def get_padded_type(T, size): fields = T._flds.copy() hints = T._hints.copy() @@ -231,6 +244,12 @@ basicsize = pto._obj.c_tp_basicsize T = get_padded_type(PyObject.TO, basicsize) py_obj = lltype.malloc(T, None, flavor="raw") + elif isinstance(w_obj, W_StringObject): + py_obj = lltype.malloc(PyStringObjectPtr.TO, None, flavor='raw') + py_obj.c_size = len(space.str_w(w_obj)) + py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) + pto = make_ref(space, space.w_str) + py_obj = rffi.cast(PyObject, py_obj) else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") pto = make_ref(space, space.type(w_obj)) @@ -255,7 +274,10 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: - raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) + if from_ref(space, ref.c_obj_type) is space.w_str: + return force_string(space, ref) + else: + raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) return obj def clear_memory(space): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h Thu Mar 25 14:59:47 2010 @@ -7,6 +7,11 @@ extern "C" { #endif +typedef struct { + PyObject_VAR_HEAD + char* buffer; + Py_ssize_t size; +} PyStringObject; #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Thu Mar 25 14:59:47 2010 @@ -1,16 +1,45 @@ -from pypy.rpython.lltypesystem import rffi -from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \ + PyStringObjectPtr, Py_ssize_t, cpython_struct, make_ref, from_ref - at cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) + at cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObjectPtr, error=None) def PyString_FromStringAndSize(space, char_p, length): - s = rffi.charpsize2str(char_p, length) - return space.wrap(s) + if char_p: + s = rffi.charpsize2str(char_p, length) + ptr = make_ref(space, space.wrap(s)) + return rffi.cast(PyStringObjectPtr, ptr) + else: + py_str = lltype.malloc(PyStringObjectPtr.TO, None, flavor='raw') + py_str.c_obj_refcnt = 1 + + buflen = length + 1 + py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') + py_str.c_buffer[buflen-1] = '\0' + py_str.c_size = length + py_str.c_obj_type = make_ref(space, space.w_str) + + return py_str @cpython_api([rffi.CCHARP], PyObject) def PyString_FromString(space, char_p): s = rffi.charp2str(char_p) return space.wrap(s) + at cpython_api([PyObject], rffi.CCHARP, error=0) +def PyString_AsString(space, ref): + ref = rffi.cast(PyStringObjectPtr, ref) + if not ref.c_buffer: + # copy string buffer + w_str = from_ref(space, ref) + s = space.str_w(w_str) + ref.c_buffer = rffi.str2charp(s) + return ref.c_buffer + @cpython_api([PyObject], Py_ssize_t, error=-1) -def PyString_Size(space, w_obj): - return space.int_w(space.len(w_obj)) +def PyString_Size(space, ref): + if from_ref(space, ref.c_obj_type) is space.w_str: + ref = rffi.cast(PyStringObjectPtr, ref) + return ref.c_size + else: + w_obj = from_ref(space, ref) + return space.int_w(space.len(w_obj)) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 14:59:47 2010 @@ -1,8 +1,16 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.test.test_cpyext import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase import py import sys +#class TestObject(BaseApiTest): +# def test_Size(self, space, api): +# skip('in progress') +# s = space.wrap("test") +# assert api.PyString_Size(s) == 4 + class AppTestStringObject(AppTestCpythonExtensionBase): def test_stringobject(self): module = self.import_extension('foo', [ @@ -41,19 +49,34 @@ raises(TypeError, module.test_Size_exception) def test_string_buffer_init(self): - skip('In progress') module = self.import_extension('foo', [ ("getstring", "METH_NOARGS", """ PyObject* s = PyString_FromStringAndSize(NULL, 3); char* c = PyString_AsString(s); - Py_ssize_t len = PyString_Size(s); + //Py_ssize_t len = PyString_Size(s); c[0] = 'a'; c[1] = 'b'; - c[len-1] = 'c'; + c[2] = 'c';//len-1] = 'c'; return s; """), ]) s = module.getstring() assert len(s) == 3 assert s == 'abc' + + + + def test_AsString(self): + module = self.import_extension('foo', [ + ("getstring", "METH_NOARGS", + """ + PyObject* s1 = PyString_FromStringAndSize("test", 4); + char* c = PyString_AsString(s1); + PyObject* s2 = PyString_FromStringAndSize(c, 4); + Py_DECREF(s1); + return s2; + """), + ]) + s = module.getstring() + assert s == 'test' From xoraxax at codespeak.net Thu Mar 25 15:01:18 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 15:01:18 +0100 (CET) Subject: [pypy-svn] r72805 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325140118.35F4A282BE5@codespeak.net> Author: xoraxax Date: Thu Mar 25 15:01:16 2010 New Revision: 72805 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Log: Add NULL check and fix force_string. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 15:01:16 2010 @@ -200,13 +200,6 @@ class InvalidPointerException(Exception): pass -def force_string(space, ref): - ref = rffi.cast(PyStringObjectPtr, ref) - s = rffi.charpsize2str(ref.c_buffer, ref.c_size) - w_str = space.wrap(s) - s_ptr = make_ref(space, w_str) - return w_str - def get_padded_type(T, size): fields = T._flds.copy() hints = T._hints.copy() @@ -266,6 +259,19 @@ # XXX borrowed references? return py_obj +def force_string(space, ref): + state = space.fromcache(State) + ref = rffi.cast(PyStringObjectPtr, ref) + s = rffi.charpsize2str(ref.c_buffer, ref.c_size) + ref = rffi.cast(PyObject, ref) + w_str = space.wrap(s) + state.py_objects_w2r[w_str] = ref + ctypes_obj = ll2ctypes.lltype2ctypes(ref) + ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value + state.py_objects_r2w[ptr] = w_str + return w_str + + def from_ref(space, ref): if not ref: return None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 15:01:16 2010 @@ -53,6 +53,8 @@ ("getstring", "METH_NOARGS", """ PyObject* s = PyString_FromStringAndSize(NULL, 3); + if (s == NULL) + return NULL; char* c = PyString_AsString(s); //Py_ssize_t len = PyString_Size(s); c[0] = 'a'; From jandem at codespeak.net Thu Mar 25 15:26:41 2010 From: jandem at codespeak.net (jandem at codespeak.net) Date: Thu, 25 Mar 2010 15:26:41 +0100 (CET) Subject: [pypy-svn] r72810 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325142641.3CAB9282BE5@codespeak.net> Author: jandem Date: Thu Mar 25 15:26:40 2010 New Revision: 72810 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Log: Rename PyStringObjectPtr to PyStringObject, for consistency with PyObject Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 15:26:40 2010 @@ -183,11 +183,11 @@ PyVarObjectFields = PyObjectFields + (("obj_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) -PyStringObject = lltype.ForwardReference() -PyStringObjectPtr = lltype.Ptr(PyStringObject) +PyStringObjectStruct = lltype.ForwardReference() +PyStringObject = lltype.Ptr(PyStringObjectStruct) PyStringObjectFields = PyVarObjectFields + \ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) -cpython_struct("PyStringObject", PyStringObjectFields, PyStringObject) +cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct) def configure(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): @@ -238,7 +238,7 @@ T = get_padded_type(PyObject.TO, basicsize) py_obj = lltype.malloc(T, None, flavor="raw") elif isinstance(w_obj, W_StringObject): - py_obj = lltype.malloc(PyStringObjectPtr.TO, None, flavor='raw') + py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw') py_obj.c_size = len(space.str_w(w_obj)) py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) @@ -261,7 +261,7 @@ def force_string(space, ref): state = space.fromcache(State) - ref = rffi.cast(PyStringObjectPtr, ref) + ref = rffi.cast(PyStringObject, ref) s = rffi.charpsize2str(ref.c_buffer, ref.c_size) ref = rffi.cast(PyObject, ref) w_str = space.wrap(s) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Thu Mar 25 15:26:40 2010 @@ -1,15 +1,15 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \ - PyStringObjectPtr, Py_ssize_t, cpython_struct, make_ref, from_ref + PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref - at cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObjectPtr, error=None) + at cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObject, error=None) def PyString_FromStringAndSize(space, char_p, length): if char_p: s = rffi.charpsize2str(char_p, length) ptr = make_ref(space, space.wrap(s)) - return rffi.cast(PyStringObjectPtr, ptr) + return rffi.cast(PyStringObject, ptr) else: - py_str = lltype.malloc(PyStringObjectPtr.TO, None, flavor='raw') + py_str = lltype.malloc(PyStringObject.TO, None, flavor='raw') py_str.c_obj_refcnt = 1 buflen = length + 1 @@ -27,7 +27,7 @@ @cpython_api([PyObject], rffi.CCHARP, error=0) def PyString_AsString(space, ref): - ref = rffi.cast(PyStringObjectPtr, ref) + ref = rffi.cast(PyStringObject, ref) if not ref.c_buffer: # copy string buffer w_str = from_ref(space, ref) @@ -38,7 +38,7 @@ @cpython_api([PyObject], Py_ssize_t, error=-1) def PyString_Size(space, ref): if from_ref(space, ref.c_obj_type) is space.w_str: - ref = rffi.cast(PyStringObjectPtr, ref) + ref = rffi.cast(PyStringObject, ref) return ref.c_size else: w_obj = from_ref(space, ref) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 15:26:40 2010 @@ -7,7 +7,6 @@ #class TestObject(BaseApiTest): # def test_Size(self, space, api): -# skip('in progress') # s = space.wrap("test") # assert api.PyString_Size(s) == 4 From xoraxax at codespeak.net Thu Mar 25 15:50:16 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 15:50:16 +0100 (CET) Subject: [pypy-svn] r72813 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325145016.32A8F282BE5@codespeak.net> Author: xoraxax Date: Thu Mar 25 15:50:14 2010 New Revision: 72813 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Also introduce the string objects to Py_DECREF. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 15:50:14 2010 @@ -280,7 +280,7 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: - if from_ref(space, ref.c_obj_type) is space.w_str: + if space.is_w(from_ref(space, ref.c_obj_type), space.w_str): return force_string(space, ref) else: raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) @@ -343,6 +343,7 @@ if callable.api_func.restype is rffi.INT_real: retval = rffi.cast(rffi.INT_real, retval) return retval + wrapper.__name__ = "wrapper for %r" % (callable, ) return wrapper #_____________________________________________________ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 15:50:14 2010 @@ -1,19 +1,24 @@ import ctypes from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref from pypy.module.cpyext.state import State # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, obj): + from pypy.module.cpyext.typeobject import string_dealloc obj.c_obj_refcnt -= 1 if obj.c_obj_refcnt == 0: state = space.fromcache(State) ptr = ctypes.addressof(obj._obj._storage) - w_obj = state.py_objects_r2w.pop(ptr) - _Py_Dealloc(space, obj) - del state.py_objects_w2r[w_obj] + if ptr not in state.py_objects_r2w and \ + space.is_w(from_ref(space, obj.c_obj_type), space.w_str): + string_dealloc(space, obj) + else: + w_obj = state.py_objects_r2w.pop(ptr) + _Py_Dealloc(space, obj) + del state.py_objects_w2r[w_obj] else: assert obj.c_obj_refcnt > 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Thu Mar 25 15:50:14 2010 @@ -2,7 +2,8 @@ from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \ PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref - at cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObject, error=None) + + at cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObject, error=lltype.nullptr(PyStringObject.TO)) def PyString_FromStringAndSize(space, char_p, length): if char_p: s = rffi.charpsize2str(char_p, length) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 15:50:14 2010 @@ -54,6 +54,10 @@ PyObject* s = PyString_FromStringAndSize(NULL, 3); if (s == NULL) return NULL; + PyObject* t = PyString_FromStringAndSize(NULL, 3); + if (t == NULL) + return NULL; + Py_DECREF(t); char* c = PyString_AsString(s); //Py_ssize_t len = PyString_Size(s); c[0] = 'a'; Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 15:50:14 2010 @@ -11,14 +11,14 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ - Py_TPFLAGS_READY, make_wrapper, Py_TPFLAGS_HEAPTYPE, make_ref + Py_TPFLAGS_READY, make_wrapper, Py_TPFLAGS_HEAPTYPE, make_ref, \ + PyStringObject from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State from pypy.module.cpyext.methodobject import generic_cpy_call from pypy.module.cpyext.macros import Py_DECREF, Py_XDECREF - PyTypeObject = lltype.ForwardReference() PyTypeObjectPtr = lltype.Ptr(PyTypeObject) PyCFunction = Ptr(FuncType([PyObject, PyObject], PyObject)) @@ -238,12 +238,22 @@ @cpython_api([PyObject], lltype.Void, external=False) +def string_dealloc(space, obj): + obj = rffi.cast(PyStringObject, obj) + pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + if obj.c_buffer: + lltype.free(obj.c_buffer, flavor="raw") + obj_voidp = rffi.cast(rffi.VOIDP_real, obj) + generic_cpy_call(space, pto.c_tp_free, obj_voidp) + pto = rffi.cast(PyObject, pto) + Py_DECREF(space, pto) + + at cpython_api([PyObject], lltype.Void, external=False) def type_dealloc(space, obj): obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) Py_XDECREF(space, base_pyo) - # type_dealloc code follows: # XXX XDECREF tp_dict, tp_bases, tp_mro, tp_cache, # tp_subclasses # free tp_doc @@ -251,7 +261,7 @@ obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) pto = rffi.cast(PyObject, type_pto) - Py_DECREF(space, type_pto) + Py_DECREF(space, pto) def allocate_type_obj(space, w_type): """ Allocates a pto from a w_type which must be a PyPy type. """ @@ -263,6 +273,8 @@ pto.c_tp_dealloc = PyObject_dealloc.api_func.get_llhelper(space) elif space.is_w(w_type, space.w_type): pto.c_tp_dealloc = type_dealloc.api_func.get_llhelper(space) + elif space.is_w(w_type, space.w_str): + pto.c_tp_dealloc = string_dealloc.api_func.get_llhelper(space) else: pto.c_tp_dealloc = subtype_dealloc.api_func.get_llhelper(space) pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE From fijal at codespeak.net Thu Mar 25 16:29:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 16:29:36 +0100 (CET) Subject: [pypy-svn] r72819 - pypy/build/bot2/pypybuildbot Message-ID: <20100325152936.67DA7282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 16:29:33 2010 New Revision: 72819 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Use File instead of DirectoryLister. Temporarily reenable pinging Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 25 16:29:33 2010 @@ -2,7 +2,7 @@ from buildbot.buildslave import BuildSlave from buildbot.status.html import WebStatus from buildbot.process.builder import Builder -from twisted.web.woven.dirlist import DirectoryLister +from twisted.web.static import File # I really wanted to pass logPath to Site from twisted.web.server import Site @@ -24,10 +24,10 @@ # Disabled. # Disable pinging, as it seems to deadlock the client -from buildbot.status.web.builder import StatusResourceBuilder -def my_ping(self, req): - raise Exception("pinging is disabled, as it seems to deadlock clients") -StatusResourceBuilder.ping = my_ping +#from buildbot.status.web.builder import StatusResourceBuilder +#def my_ping(self, req): +# raise Exception("pinging is disabled, as it seems to deadlock clients") +#StatusResourceBuilder.ping = my_ping # Disabled. # Picking a random slave is not really what we want; @@ -45,8 +45,8 @@ 'windows', 'mac', 'benchmark-run', 'other'])) -status.putChild('nightly', DirectoryLister(os.path.expanduser('~/nightly'), - defaultType='application/octet-stream')) +status.putChild('nightly', File(os.path.expanduser('~/nightly'), + defaultType='application/octet-stream')) pypybuilds = load('pypybuildbot.builds') From fijal at codespeak.net Thu Mar 25 16:33:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 16:33:43 +0100 (CET) Subject: [pypy-svn] r72820 - pypy/build/bot2/pypybuildbot Message-ID: <20100325153343.B694B282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 16:33:41 2010 New Revision: 72820 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Reenable disabling of pinging. I can't make it work anyway Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 25 16:33:41 2010 @@ -24,10 +24,10 @@ # Disabled. # Disable pinging, as it seems to deadlock the client -#from buildbot.status.web.builder import StatusResourceBuilder -#def my_ping(self, req): -# raise Exception("pinging is disabled, as it seems to deadlock clients") -#StatusResourceBuilder.ping = my_ping +from buildbot.status.web.builder import StatusResourceBuilder +def my_ping(self, req): + raise Exception("pinging is disabled, as it seems to deadlock clients") +StatusResourceBuilder.ping = my_ping # Disabled. # Picking a random slave is not really what we want; From fijal at codespeak.net Thu Mar 25 16:40:21 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 16:40:21 +0100 (CET) Subject: [pypy-svn] r72821 - pypy/build/bot2/pypybuildbot Message-ID: <20100325154021.C4BAF282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 16:40:20 2010 New Revision: 72821 Modified: pypy/build/bot2/pypybuildbot/master.py Log: another approach Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 25 16:40:20 2010 @@ -45,8 +45,8 @@ 'windows', 'mac', 'benchmark-run', 'other'])) -status.putChild('nightly', File(os.path.expanduser('~/nightly'), - defaultType='application/octet-stream')) +status.site.resource.putChild('nightly', File(os.path.expanduser('~/nightly'), + defaultType='application/octet-stream')) pypybuilds = load('pypybuildbot.builds') From fijal at codespeak.net Thu Mar 25 16:41:51 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 16:41:51 +0100 (CET) Subject: [pypy-svn] r72822 - pypy/build/bot2/pypybuildbot Message-ID: <20100325154151.72887282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 16:41:50 2010 New Revision: 72822 Modified: pypy/build/bot2/pypybuildbot/master.py Log: grumble grumble grumble. make reconfig does not do all I want it to, needs restart, otherwise works Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 25 16:41:50 2010 @@ -45,8 +45,8 @@ 'windows', 'mac', 'benchmark-run', 'other'])) -status.site.resource.putChild('nightly', File(os.path.expanduser('~/nightly'), - defaultType='application/octet-stream')) +status.putChild('nightly', File(os.path.expanduser('~/nightly'), + defaultType='application/octet-stream')) pypybuilds = load('pypybuildbot.builds') From arigo at codespeak.net Thu Mar 25 16:43:45 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 16:43:45 +0100 (CET) Subject: [pypy-svn] r72823 - pypy/branch/fix-64/pypy/rpython/tool/test Message-ID: <20100325154345.A1B89282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 16:43:44 2010 New Revision: 72823 Modified: pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Log: Write a test about what I would like to have. Modified: pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Thu Mar 25 16:43:44 2010 @@ -256,3 +256,88 @@ library_dirs = [str(tmpdir)] ) rffi_platform.verify_eci(eci) + +def test_generate_padding(): + # 'padding_drop' is a bit strange, but is what we need to write C code + # that defines prebuilt structures of that type. Normally, the C + # backend would generate '0' entries for every field c__pad#. That's + # usually much more than the number of real fields in the real structure + # definition. So 'padding_drop' allows a quick fix: it lists fields + # that should be ignored by the C backend. It should only be used in + # that situation because it lists some of the c__pad# fields a bit + # randomly -- to the effect that writing '0' for the other fields gives + # the right amount of '0's. + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + assert S._hints['padding_drop'] == ('c__pad0',) + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + assert S._hints['padding_drop'] == () + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2') + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + char c3; /* _pad1 */ + /* _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + assert S._hints['padding_drop'] == ('c__pad2',) + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + /* _pad0 */ + short s1; /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2') + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + char c3; /* _pad3 */ + /* _pad4 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2', + 'c__pad3', 'c__pad4') + assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2', 'c__pad4') From arigo at codespeak.net Thu Mar 25 17:36:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 17:36:27 +0100 (CET) Subject: [pypy-svn] r72828 - in pypy/branch/fix-64/pypy/rpython/tool: . test Message-ID: <20100325163627.A8048282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 17:36:26 2010 New Revision: 72828 Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Log: Whack whack whack until the test passes. Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py Thu Mar 25 17:36:26 2010 @@ -299,11 +299,16 @@ fieldoffsets.append(offset) seen[cell] = True + allfields = tuple(['c_' + name for name, _ in fields]) + padfields = tuple(padfields) name = self.name + padding_drop = PaddingDrop(name, allfields, padfields, + config_result.CConfig._compilation_info_) hints = {'align': info['align'], 'size': info['size'], 'fieldoffsets': tuple(fieldoffsets), - 'padding': tuple(padfields)} + 'padding': padfields, + 'get_padding_drop': padding_drop} if name.startswith('struct '): name = name[7:] else: @@ -477,6 +482,85 @@ return info['size'] # ____________________________________________________________ + +class PaddingDrop(object): + # Compute (lazily) the padding_drop for a structure. + # See test_generate_padding for more information. + cache = None + + def __init__(self, name, allfields, padfields, eci): + self.name = name + self.allfields = allfields + self.padfields = padfields + self.eci = eci + + def __call__(self, types): + if self.cache is None: + self.compute_now(types) + return self.cache + + def compute_now(self, types): + # Some simplifying assumptions there. We assume that all fields + # are either integers or pointers, so can be written in C as '0'. + # We also assume that the C backend gives us in 'types' a dictionary + # mapping non-padding field names to their C type (without '@'). + drops = [] + staticfields = [] + consecutive_pads = [] + for fieldname in self.allfields: + if fieldname in self.padfields: + consecutive_pads.append(fieldname) + continue + staticfields.append(types[fieldname]) + if consecutive_pads: + # In that case we have to ask: how many of these pads are + # really needed? The correct answer might be between none + # and all of the pads listed in 'consecutive_pads'. + for i in range(len(consecutive_pads)+1): + class CConfig: + _compilation_info_ = self.eci + FIELDLOOKUP = _PaddingDropFieldLookup(self.name, + staticfields, + fieldname) + got = configure(CConfig)['FIELDLOOKUP'] + if got == 1: + break # found + staticfields.insert(-1, None) + else: + raise Exception("could not determine the detailed field" + " layout of %r" % (self.name,)) + # succeeded with 'i' pads. Drop all pads beyond that. + drops += consecutive_pads[i:] + consecutive_pads = [] + self.cache = drops + +class _PaddingDropFieldLookup(CConfigEntry): + def __init__(self, name, staticfields, fieldname): + self.name = name + self.staticfields = staticfields + self.fieldname = fieldname + + def prepare_code(self): + yield 'typedef %s platcheck_t;' % (self.name,) + yield 'static platcheck_t s = {' + for i, type in enumerate(self.staticfields): + if i == len(self.staticfields)-1: + value = -1 + else: + value = 0 + if type: + yield '\t(%s)%s,' % (type, value) + else: + yield '\t%s,' % (value,) + yield '};' + fieldname = self.fieldname + assert fieldname.startswith('c_') + yield 'dump("fieldlookup", s.%s != 0);' % (fieldname[2:],) + + def build_result(self, info, config_result): + return info['fieldlookup'] + +# ____________________________________________________________ # # internal helpers Modified: pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Thu Mar 25 17:36:26 2010 @@ -275,7 +275,8 @@ """, [("c1", lltype.Signed), ("s1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0',) - assert S._hints['padding_drop'] == ('c__pad0',) + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad0'] # S = rffi_platform.getstruct("foobar_t", """ typedef struct { @@ -286,7 +287,8 @@ """, [("c1", lltype.Signed), ("s1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0',) - assert S._hints['padding_drop'] == () + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == [] # S = rffi_platform.getstruct("foobar_t", """ typedef struct { @@ -298,7 +300,8 @@ """, [("c1", lltype.Signed), ("i1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') - assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] # S = rffi_platform.getstruct("foobar_t", """ typedef struct { @@ -311,7 +314,8 @@ """, [("c1", lltype.Signed), ("i1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') - assert S._hints['padding_drop'] == ('c__pad2',) + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad2'] # S = rffi_platform.getstruct("foobar_t", """ typedef struct { @@ -323,7 +327,8 @@ """, [("c1", lltype.Signed), ("i1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') - assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] # S = rffi_platform.getstruct("foobar_t", """ typedef struct { @@ -340,4 +345,5 @@ ("s1", lltype.Signed)]) assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2', 'c__pad3', 'c__pad4') - assert S._hints['padding_drop'] == ('c__pad1', 'c__pad2', 'c__pad4') + d = {'c_c1': 'char', 'c_i1': 'int', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2', 'c__pad4'] From arigo at codespeak.net Thu Mar 25 17:49:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 17:49:57 +0100 (CET) Subject: [pypy-svn] r72829 - in pypy/branch/fix-64/pypy/rpython/tool: . test Message-ID: <20100325164957.B50FC282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 17:49:56 2010 New Revision: 72829 Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Log: One more test, fix the code. Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py Thu Mar 25 17:49:56 2010 @@ -532,6 +532,7 @@ # succeeded with 'i' pads. Drop all pads beyond that. drops += consecutive_pads[i:] consecutive_pads = [] + drops += consecutive_pads # drop the final pads too self.cache = drops class _PaddingDropFieldLookup(CConfigEntry): Modified: pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/test/test_rffi_platform.py Thu Mar 25 17:49:56 2010 @@ -347,3 +347,13 @@ 'c__pad3', 'c__pad4') d = {'c_c1': 'char', 'c_i1': 'int', 'c_s1': 'short'} assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2', 'c__pad4'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + long l2; /* some number of _pads */ + } foobar_t; + """, [("c1", lltype.Signed)]) + padding = list(S._hints['padding']) + d = {'c_c1': 'char'} + assert S._hints['get_padding_drop'](d) == padding From arigo at codespeak.net Thu Mar 25 17:56:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 17:56:09 +0100 (CET) Subject: [pypy-svn] r72830 - pypy/branch/fix-64/pypy/rpython/tool Message-ID: <20100325165609.9B87A282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 17:56:08 2010 New Revision: 72830 Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py Log: Ignoring CompilationErrors looks kinda good here. Modified: pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/fix-64/pypy/rpython/tool/rffi_platform.py Thu Mar 25 17:56:08 2010 @@ -522,9 +522,12 @@ FIELDLOOKUP = _PaddingDropFieldLookup(self.name, staticfields, fieldname) - got = configure(CConfig)['FIELDLOOKUP'] - if got == 1: - break # found + try: + got = configure(CConfig)['FIELDLOOKUP'] + if got == 1: + break # found + except CompilationError: + pass staticfields.insert(-1, None) else: raise Exception("could not determine the detailed field" From arigo at codespeak.net Thu Mar 25 17:56:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 17:56:36 +0100 (CET) Subject: [pypy-svn] r72831 - in pypy/branch/fix-64/pypy/translator/c: . test Message-ID: <20100325165636.2CF44282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 17:56:35 2010 New Revision: 72831 Modified: pypy/branch/fix-64/pypy/translator/c/node.py pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py Log: Fix test_padding_in_prebuilt_struct() in genc. Modified: pypy/branch/fix-64/pypy/translator/c/node.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/node.py (original) +++ pypy/branch/fix-64/pypy/translator/c/node.py Thu Mar 25 17:56:35 2010 @@ -571,7 +571,19 @@ if hasattr(self.T, "_hints") and self.T._hints.get('union'): data = data[0:1] + if 'get_padding_drop' in self.T._hints: + d = {} + for name, _ in data: + T = defnode.c_struct_field_type(name) + typename = self.db.gettype(T) + d[name] = cdecl(typename, '') + padding_drop = self.T._hints['get_padding_drop'](d) + else: + padding_drop = [] + for name, value in data: + if name in padding_drop: + continue c_expr = defnode.access_expr(self.name, name) lines = generic_initializationexpr(self.db, value, c_expr, decoration + name) Modified: pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/branch/fix-64/pypy/translator/c/test/test_lltyped.py Thu Mar 25 17:56:35 2010 @@ -804,6 +804,7 @@ ("s1", Signed), ("l3", Signed)]) S = rffi_platform.configure(CConfig)['STRUCT'] + assert 'get_padding_drop' in S._hints s1 = malloc(S, immortal=True) s1.c_c1 = rffi.cast(S.c_c1, -12) s1.c_s1 = rffi.cast(S.c_s1, -7843) From fijal at codespeak.net Thu Mar 25 18:10:29 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 18:10:29 +0100 (CET) Subject: [pypy-svn] r72833 - pypy/branch/kill-asm-call Message-ID: <20100325171029.F2E23282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 18:10:28 2010 New Revision: 72833 Added: pypy/branch/kill-asm-call/ - copied from r72832, pypy/trunk/ Log: A branch to kill assembler-based do_call From afa at codespeak.net Thu Mar 25 18:40:18 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 25 Mar 2010 18:40:18 +0100 (CET) Subject: [pypy-svn] r72837 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325174018.AE7DE282BDB@codespeak.net> Author: afa Date: Thu Mar 25 18:40:16 2010 New Revision: 72837 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Improve reference counting, especially when type(x) == x (which happens for x=type) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Thu Mar 25 18:40:16 2010 @@ -38,3 +38,5 @@ import pypy.module.cpyext.stringobject import pypy.module.cpyext.tupleobject import pypy.module.cpyext.dictobject +# now that all rffi_platform.Struct types are registered, configure them +api.configure_types() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 18:40:16 2010 @@ -66,8 +66,8 @@ # Functions may raise exceptions. In context (3), the exception flows normally # through the calling function. In context (1) and (2), the exception is # caught; if it is an OperationError, it is stored in the thread state; other -# exceptions generate a OperationError(w_SystemError). In every case the -# funtion returns the error value specifed in the API. +# exceptions generate a OperationError(w_SystemError); and the funtion returns +# the error value specifed in the API. # class ApiFunction: @@ -189,7 +189,7 @@ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct) -def configure(): +def configure_types(): for name, TYPE in rffi_platform.configure(CConfig).iteritems(): if name in TYPES: TYPES[name].become(TYPE) @@ -215,6 +215,7 @@ return lltype.Struct(hints["c_name"], hints=hints, *new_fields) def make_ref(space, w_obj, borrowed=False, steal=False): + from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, DEBUG_REFCOUNT if w_obj is None: return lltype.nullptr(PyObject.TO) assert isinstance(w_obj, W_Root) @@ -226,36 +227,44 @@ w_type = space.type(w_obj) if space.is_w(w_type, space.w_type): py_obj = allocate_type_obj(space, w_obj) + py_obj.c_obj_refcnt = 1 if space.is_w(w_type, w_obj): pto = py_obj + Py_INCREF(space, pto) else: pto = make_ref(space, w_type) elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) pto = w_type.pto + # Don't increase refcount for non-heaptypes + # Py_INCREF(space, pto) basicsize = pto._obj.c_tp_basicsize T = get_padded_type(PyObject.TO, basicsize) py_obj = lltype.malloc(T, None, flavor="raw") + py_obj.c_obj_refcnt = 1 elif isinstance(w_obj, W_StringObject): py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw') py_obj.c_size = len(space.str_w(w_obj)) py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) py_obj = rffi.cast(PyObject, py_obj) + py_obj.c_obj_refcnt = 1 else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + py_obj.c_obj_refcnt = 1 pto = make_ref(space, space.type(w_obj)) py_obj.c_obj_type = rffi.cast(PyObject, pto) - py_obj.c_obj_refcnt = 1 ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) py_obj = rffi.cast(PyObject, py_obj) + if DEBUG_REFCOUNT: + print "MAKREF", py_obj, w_obj state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj elif not steal: - py_obj.c_obj_refcnt += 1 + Py_INCREF(space, py_obj) # XXX borrowed references? return py_obj @@ -299,6 +308,7 @@ w_obj_type = space.type(w_obj) return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) +# Make the wrapper for the cases (1) and (2) def make_wrapper(space, callable): def wrapper(*args): boxed_args = [] @@ -381,8 +391,6 @@ pypy_rename_h.write('\n'.join(pypy_rename)) - configure() # needs pypy_rename.h - # Structure declaration code members = [] for name, func in FUNCTIONS.iteritems(): @@ -508,6 +516,8 @@ FT = lltype.typeOf(func).TO if FT.RESULT is PyObject: ret = from_ref(space, result) + if result: + Py_DECREF(space, result) # Check for exception consistency has_error = PyErr_Occurred(space) is not None @@ -523,11 +533,10 @@ state = space.fromcache(State) state.check_and_raise_exception() - Py_DECREF(space, ret) # XXX WHY?? return ret finally: if decref_args: - for arg in args: # XXX ur needed - if arg is not None and isinstance(arg, W_Root): - Py_DECREF(space, arg) + for arg, ref in zip(args, boxed_args): + if isinstance(arg, W_Root) and ref: + Py_DECREF(space, ref) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 18:40:16 2010 @@ -4,11 +4,15 @@ from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref from pypy.module.cpyext.state import State +DEBUG_REFCOUNT = False + # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, obj): from pypy.module.cpyext.typeobject import string_dealloc obj.c_obj_refcnt -= 1 + if DEBUG_REFCOUNT: + print "DECREF", obj, obj.c_obj_refcnt if obj.c_obj_refcnt == 0: state = space.fromcache(State) ptr = ctypes.addressof(obj._obj._storage) @@ -25,6 +29,8 @@ @cpython_api([PyObject], lltype.Void) def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 + if DEBUG_REFCOUNT: + print "INCREF", obj, obj.c_obj_refcnt @cpython_api([PyObject], lltype.Void) def Py_XDECREF(space, obj): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/conftest.py Thu Mar 25 18:40:16 2010 @@ -1,12 +1,19 @@ import py -from pypy.conftest import option +from pypy.conftest import option, gettestobjspace class Directory(py.test.collect.Directory): def collect(self): if option.runappdirect: py.test.skip("cannot be run by py.test -A") + + # ensure additional functions are registered + import pypy.module.cpyext.test.test_cpyext + return super(Directory, self).collect() +def pytest_funcarg__space(request): + return gettestobjspace(usemodules=['cpyext']) + def pytest_funcarg__api(request): return request.cls.api Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py Thu Mar 25 18:40:16 2010 @@ -0,0 +1,32 @@ +from pypy.conftest import gettestobjspace +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.interpreter.baseobjspace import W_Root +from pypy.module.cpyext.state import State +from pypy.module.cpyext import api +PyObject = api.PyObject + + at api.cpython_api([PyObject], lltype.Void) +def PyPy_GetWrapped(space, w_arg): + assert isinstance(w_arg, W_Root) + at api.cpython_api([PyObject], lltype.Void) +def PyPy_GetReference(space, arg): + assert lltype.typeOf(arg) is PyObject + +class BaseApiTest: + def setup_class(cls): + cls.space = gettestobjspace(usemodules=['cpyext']) + class CAPI: + def __getattr__(self, name): + return getattr(cls.space, name) + cls.api = CAPI() + CAPI.__dict__.update(api.INTERPLEVEL_API) + + def teardown_method(self, func): + state = self.space.fromcache(State) + assert state.exc_value is None + +class TestConversion(BaseApiTest): + def test_conversions(self, space, api): + api.PyPy_GetWrapped(space.w_None) + api.PyPy_GetReference(space.w_None) + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Thu Mar 25 18:40:16 2010 @@ -12,7 +12,6 @@ from pypy.module.cpyext.macros import Py_DECREF from pypy.translator.goal import autopath - @api.cpython_api([], api.PyObject) def PyPy_Crash1(space): 1/0 @@ -54,18 +53,6 @@ standalone=False) return str(soname) -class BaseApiTest: - def setup_class(cls): - class CAPI: - def __getattr__(self, name): - return getattr(cls.space, name) - cls.api = CAPI() - CAPI.__dict__.update(api.INTERPLEVEL_API) - - def teardown_method(self, func): - state = self.space.fromcache(State) - assert state.exc_value is None - class AppTestCpythonExtensionBase: def setup_class(cls): cls.space = gettestobjspace(usemodules=['cpyext']) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Thu Mar 25 18:40:16 2010 @@ -1,4 +1,4 @@ -from pypy.module.cpyext.test.test_cpyext import BaseApiTest +from pypy.module.cpyext.test.test_api import BaseApiTest class TestFloatObject(BaseApiTest): def test_floatobject(self, space, api): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Thu Mar 25 18:40:16 2010 @@ -1,4 +1,4 @@ -from pypy.module.cpyext.test.test_cpyext import BaseApiTest +from pypy.module.cpyext.test.test_api import BaseApiTest class TestObject(BaseApiTest): def test_IsTrue(self, space, api): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Thu Mar 25 18:40:16 2010 @@ -1,5 +1,5 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.test.test_cpyext import BaseApiTest +from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase import py @@ -51,15 +51,19 @@ module = self.import_extension('foo', [ ("getstring", "METH_NOARGS", """ - PyObject* s = PyString_FromStringAndSize(NULL, 3); + PyObject *s, *t; + char* c; + Py_ssize_t len; + + s = PyString_FromStringAndSize(NULL, 3); if (s == NULL) return NULL; - PyObject* t = PyString_FromStringAndSize(NULL, 3); + t = PyString_FromStringAndSize(NULL, 3); if (t == NULL) return NULL; Py_DECREF(t); - char* c = PyString_AsString(s); - //Py_ssize_t len = PyString_Size(s); + c = PyString_AsString(s); + //len = PyString_Size(s); c[0] = 'a'; c[1] = 'b'; c[2] = 'c';//len-1] = 'c'; Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Thu Mar 25 18:40:16 2010 @@ -1,6 +1,4 @@ -import py.test - -from pypy.module.cpyext.test.test_cpyext import BaseApiTest +from pypy.module.cpyext.test.test_api import BaseApiTest class TestTupleObject(BaseApiTest): def test_tupleobject(self, space, api): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 18:40:16 2010 @@ -11,7 +11,7 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ - Py_TPFLAGS_READY, make_wrapper, Py_TPFLAGS_HEAPTYPE, make_ref, \ + Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ PyStringObject from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs @@ -283,9 +283,8 @@ pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out bases_w = w_type.bases_w assert len(bases_w) <= 1 - if not bases_w: - pto.c_tp_base = lltype.nullptr(PyTypeObject) - elif not space.is_w(w_type, space.w_type): # avoid endless recursion + pto.c_tp_base = lltype.nullptr(PyTypeObject) + if bases_w and not space.is_w(w_type, space.w_type): # avoid endless recursion ref = make_ref(space, bases_w[0]) pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref) # XXX fill slots in pto From fijal at codespeak.net Thu Mar 25 18:53:32 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 18:53:32 +0100 (CET) Subject: [pypy-svn] r72840 - in pypy/branch/kill-asm-call/pypy/jit/backend/llsupport: . test Message-ID: <20100325175332.B19D8282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 18:53:30 2010 New Revision: 72840 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Log: IN-PROGRESS Start writing descr in a way that has a little stub instead of assembler calls Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Thu Mar 25 18:53:30 2010 @@ -1,3 +1,4 @@ +import py from pypy.rpython.lltypesystem import lltype from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr @@ -198,6 +199,7 @@ _returns_a_pointer = False # unless overridden by GcPtrCallDescr _returns_a_float = False # unless overridden by FloatCallDescr + _returns_a_void = False # unless overridden by VoidCallDescr def returns_a_pointer(self): return self._returns_a_pointer @@ -205,39 +207,48 @@ def returns_a_float(self): return self._returns_a_float + def returns_a_void(self): + return self._returns_a_void + def get_result_size(self, translate_support_code): raise NotImplementedError - def get_token_for_call(self, cpu): - if self.loop_token is not None: - return self.loop_token - args = [BoxInt()] + self.instantiate_arg_classes() - if self.get_result_size(cpu.translate_support_code) == 0: - result = None - result_list = [] - else: - if self.returns_a_pointer(): - result = BoxPtr() - elif self.returns_a_float(): - result = BoxFloat() + def get_call_stub(self): + return self.call_stub + + def create_call_stub(self, FUNC): + def no_result(arg): + return None + + def process(no, c): + if c == 'i': + return 'lltype.cast_primitive(FUNC.ARGS[%d], arg[%d].getint())' % (no, no) + elif c == 'f': + return 'args[%d].getfloat()' % (no,) + elif c == 'r': + return 'arg[%d].getptr(FUNC.ARGS[%d])' % (no, no) else: - result = BoxInt() - result_list = [result] - operations = [ - ResOperation(rop.CALL, args[:], result, self), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None, - descr=BasicFailDescr()), - ResOperation(rop.FINISH, result_list, None, - descr=BasicFailDescr())] - operations[1].fail_args = [] - loop_token = LoopToken() - # note: the 'args' that we pass below is not the same object as the - # 'args[:]' that was passed above to ResOperation, because we want - # the argument to ResOperation to be non-resizable, but the argument - # to compile_loop to be resizable. - cpu.compile_loop(args, operations, loop_token) - self.loop_token = loop_token - return loop_token + raise Exception("Unknown type %s for type %s" % (c, TP)) + + if self.returns_a_pointer(): + restype = 'BoxPtr' + elif self.returns_a_float(): + restype = 'BoxFloat' + elif self.returns_a_void(): + restype = 'no_result' + else: + restype = 'BoxInt' + args = ", ".join([process(i, c) for i, c in + enumerate(self.arg_classes)]) + source = py.code.Source(""" + def call_stub(callable, args): + ll_callable = lltype.cast_opaque_ptr(FUNC, callable) + return %(restype)s(ll_callable(%(args)s)) + """ % locals()) + d = locals().copy() + d['lltype'] = lltype + exec source.compile() in d + self.call_stub = d['call_stub'] def repr_of_descr(self): return '<%s>' % self._clsname @@ -254,6 +265,8 @@ class VoidCallDescr(NonGcPtrCallDescr): _clsname = 'VoidCallDescr' + _returns_a_void = True + def get_result_size(self, translate_support_code): return 0 @@ -281,6 +294,7 @@ return cache[key] except KeyError: calldescr = cls(arg_classes, extrainfo) + calldescr.create_call_stub(lltype.FuncType(ARGS, RESULT)) cache[key] = calldescr return calldescr Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Thu Mar 25 18:53:30 2010 @@ -2,7 +2,8 @@ from pypy.jit.backend.llsupport.descr import * from pypy.jit.backend.llsupport import symbolic from pypy.rlib.objectmodel import Symbolic - +from pypy.rpython.annlowlevel import llhelper +from pypy.jit.metainterp.history import BoxInt def test_get_size_descr(): c0 = GcCache(False) @@ -227,3 +228,17 @@ # descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float) assert 'FloatCallDescr' in descr4f.repr_of_descr() + +def test_call_stubs(): + c0 = GcCache(False) + ARGS = [lltype.Char, lltype.Signed] + RES = lltype.Char + descr1 = get_call_descr(c0, ARGS, RES) + def f(a, b): + return 'c' + + call_stub = descr1.get_call_stub() + fnptr = llhelper(lltype.FuncType(ARGS, RES), f) + + res = call_stub(fnptr, [BoxInt(1), BoxInt(2)]) + assert res.getint() == ord('c') From xoraxax at codespeak.net Thu Mar 25 19:24:41 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 19:24:41 +0100 (CET) Subject: [pypy-svn] r72841 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325182441.CFDA4282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 25 19:24:40 2010 New Revision: 72841 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Add comments and TODO items. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Thu Mar 25 19:24:40 2010 @@ -2,8 +2,14 @@ - Complete the PyTypeObject initialization code. - properly support "borrowed" references: the PyObject must be stored somewhere + - Use a WeakKeyDictionary to count how often a PyObject is allocated for + a given wrapped object and use this to assess whether optimizations are + useful - lltype.free in PyObject_Del() sometimes raise an exception (but all tests pass) + - Reported by Amaury + - Alexander cannot reproduce it + PyStringObject support ====================== Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 19:24:40 2010 @@ -18,6 +18,8 @@ ptr = ctypes.addressof(obj._obj._storage) if ptr not in state.py_objects_r2w and \ space.is_w(from_ref(space, obj.c_obj_type), space.w_str): + # this is a half-allocated string, lets call the deallocator + # directly string_dealloc(space, obj) else: w_obj = state.py_objects_r2w.pop(ptr) From xoraxax at codespeak.net Thu Mar 25 19:25:02 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 19:25:02 +0100 (CET) Subject: [pypy-svn] r72842 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325182502.93155282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 25 19:25:00 2010 New Revision: 72842 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Add borrowed=True to PyTuple_GetItem. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Thu Mar 25 19:25:00 2010 @@ -23,7 +23,7 @@ Py_DECREF(space, w_obj) # SetItem steals a reference! XXX this needs to go into the wrapper return 0 - at cpython_api([PyObject, Py_ssize_t], PyObject) + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) def PyTuple_GetItem(space, w_t, pos): if not PyTuple_Check(space, w_t): PyErr_BadInternalCall(space) From arigo at codespeak.net Thu Mar 25 19:29:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 19:29:55 +0100 (CET) Subject: [pypy-svn] r72843 - in pypy/trunk/pypy: lib lib/app_test module/_socket/test module/readline/test objspace/std rpython/lltypesystem rpython/test rpython/tool rpython/tool/test translator/c translator/c/test Message-ID: <20100325182955.38865282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 19:29:52 2010 New Revision: 72843 Modified: pypy/trunk/pypy/lib/app_test/test_dbm_extra.py pypy/trunk/pypy/lib/resource.py pypy/trunk/pypy/module/_socket/test/test_sock_app.py pypy/trunk/pypy/module/readline/test/test_c_readline.py pypy/trunk/pypy/module/readline/test/test_with_pypy.py pypy/trunk/pypy/objspace/std/typeobject.py pypy/trunk/pypy/rpython/lltypesystem/lltype.py pypy/trunk/pypy/rpython/lltypesystem/opimpl.py pypy/trunk/pypy/rpython/test/test_rbuiltin.py pypy/trunk/pypy/rpython/test/test_rdict.py pypy/trunk/pypy/rpython/test/test_rint.py pypy/trunk/pypy/rpython/tool/rffi_platform.py pypy/trunk/pypy/rpython/tool/rfficache.py pypy/trunk/pypy/rpython/tool/test/test_rffi_platform.py pypy/trunk/pypy/translator/c/genc.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/test/test_lltyped.py pypy/trunk/pypy/translator/c/test/test_newgc.py pypy/trunk/pypy/translator/c/test/test_typed.py Log: Merge branch/fix-64. Modified: pypy/trunk/pypy/lib/app_test/test_dbm_extra.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/test_dbm_extra.py (original) +++ pypy/trunk/pypy/lib/app_test/test_dbm_extra.py Thu Mar 25 19:29:52 2010 @@ -1,6 +1,9 @@ import py -from pypy.lib import dbm from pypy.tool.udir import udir +try: + from pypy.lib import dbm +except ImportError, e: + py.test.skip(e) def test_get(): path = str(udir.join('test_dbm_extra.test_get')) Modified: pypy/trunk/pypy/lib/resource.py ============================================================================== --- pypy/trunk/pypy/lib/resource.py (original) +++ pypy/trunk/pypy/lib/resource.py Thu Mar 25 19:29:52 2010 @@ -28,8 +28,8 @@ class timeval(Structure): _fields_ = ( - ("tv_sec", c_int), - ("tv_usec", c_int), + ("tv_sec", c_long), + ("tv_usec", c_long), ) def __str__(self): return "(%s, %s)" % (self.tv_sec, self.tv_usec) 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 Thu Mar 25 19:29:52 2010 @@ -32,13 +32,17 @@ def test_gethostbyaddr(): host = "localhost" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds host = "127.0.0.1" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds def test_getservbyname(): name = "smtp" Modified: pypy/trunk/pypy/module/readline/test/test_c_readline.py ============================================================================== --- pypy/trunk/pypy/module/readline/test/test_c_readline.py (original) +++ pypy/trunk/pypy/module/readline/test/test_c_readline.py Thu Mar 25 19:29:52 2010 @@ -2,8 +2,14 @@ Directly test the basic ctypes wrappers. """ +import py from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() -from pypy.module.readline import c_readline +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) def test_basic_import(): Modified: pypy/trunk/pypy/module/readline/test/test_with_pypy.py ============================================================================== --- pypy/trunk/pypy/module/readline/test/test_with_pypy.py (original) +++ pypy/trunk/pypy/module/readline/test/test_with_pypy.py Thu Mar 25 19:29:52 2010 @@ -3,7 +3,14 @@ in the PyPy interpreter, itself running on top of CPython """ +import py from pypy.conftest import gettestobjspace +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) class AppTestReadline: Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Thu Mar 25 19:29:52 2010 @@ -264,7 +264,8 @@ @purefunction def _pure_lookup_where_with_method_cache(w_self, name, version_tag): space = w_self.space - SHIFT = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + SHIFT2 = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + SHIFT1 = SHIFT2 - 5 version_tag_as_int = current_object_addr_as_int(version_tag) # ^^^Note: if the version_tag object is moved by a moving GC, the # existing method cache entries won't be found any more; new @@ -273,7 +274,12 @@ # the time - so using the fast current_object_addr_as_int() instead # of a slower solution like hash() is still a good trade-off. hash_name = compute_hash(name) - method_hash = r_uint(intmask(version_tag_as_int * hash_name)) >> SHIFT + product = intmask(version_tag_as_int * hash_name) + method_hash = (r_uint(product) ^ (r_uint(product) << SHIFT1)) >> SHIFT2 + # ^^^Note2: we used to just take product>>SHIFT2, but on 64-bit + # platforms SHIFT2 is really large, and we loose too much information + # that way (as shown by failures of the tests that typically have + # method names like 'f' who hash to a number that has only ~33 bits). cached_version_tag = space.method_cache_versions[method_hash] if cached_version_tag is version_tag: cached_name = space.method_cache_names[method_hash] Modified: pypy/trunk/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/lltype.py Thu Mar 25 19:29:52 2010 @@ -1494,8 +1494,13 @@ if n < 0: raise ValueError, "negative array length" _parentable.__init__(self, TYPE) - self.items = [TYPE.OF._allocate(initialization=initialization, parent=self, parentindex=j) - for j in range(n)] + try: + myrange = range(n) + except OverflowError: + raise MemoryError("definitely too many items") + self.items = [TYPE.OF._allocate(initialization=initialization, + parent=self, parentindex=j) + for j in myrange] if parent is not None: self._setparentstructure(parent, parentindex) Modified: pypy/trunk/pypy/rpython/lltypesystem/opimpl.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/opimpl.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/opimpl.py Thu Mar 25 19:29:52 2010 @@ -18,13 +18,20 @@ # global synonyms for some types from pypy.rlib.rarithmetic import intmask -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong -type_by_name = { +if r_longlong is r_int: + r_longlong_arg = (r_longlong, int) + r_longlong_result = int +else: + r_longlong_arg = r_longlong + r_longlong_result = r_longlong + +argtype_by_name = { 'int': int, 'float': float, 'uint': r_uint, - 'llong': r_longlong, + 'llong': r_longlong_arg, 'ullong': r_ulonglong, } @@ -56,9 +63,9 @@ adjust_result = intmask else: adjust_result = no_op - assert typname in type_by_name, "%s: not a primitive op" % ( + assert typname in argtype_by_name, "%s: not a primitive op" % ( fullopname,) - argtype = type_by_name[typname] + argtype = argtype_by_name[typname] if opname in ops_unary: def op_function(x): @@ -226,16 +233,16 @@ return r def op_llong_floordiv(x, y): - assert isinstance(x, r_longlong) - assert isinstance(y, r_longlong) + assert isinstance(x, r_longlong_arg) + assert isinstance(y, r_longlong_arg) r = x//y if x^y < 0 and x%y != 0: r += 1 return r def op_llong_mod(x, y): - assert isinstance(x, r_longlong) - assert isinstance(y, r_longlong) + assert isinstance(x, r_longlong_arg) + assert isinstance(y, r_longlong_arg) r = x%y if x^y < 0 and x%y != 0: r -= y @@ -258,7 +265,7 @@ return float(u) def op_cast_longlong_to_float(i): - assert type(i) is r_longlong + assert isinstance(i, r_longlong_arg) # take first 31 bits li = float(int(i & r_longlong(0x7fffffff))) ui = float(int(i >> 31)) * float(0x80000000) @@ -290,7 +297,7 @@ small = f / r high = int(small) truncated = int((small - high) * r) - return r_longlong(high) * 0x100000000 + truncated + return r_longlong_result(high) * 0x100000000 + truncated def op_cast_char_to_int(b): assert type(b) is str and len(b) == 1 @@ -314,10 +321,10 @@ def op_cast_int_to_longlong(b): assert type(b) is int - return r_longlong(b) + return r_longlong_result(b) def op_truncate_longlong_to_int(b): - assert type(b) is r_longlong + assert isinstance(b, r_longlong_arg) return intmask(b) def op_cast_pointer(RESTYPE, obj): Modified: pypy/trunk/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/trunk/pypy/rpython/test/test_rbuiltin.py Thu Mar 25 19:29:52 2010 @@ -5,7 +5,8 @@ from pypy.rlib.debug import llinterpcall from pypy.rpython.lltypesystem import lltype from pypy.tool import udir -from pypy.rlib.rarithmetic import r_uint, intmask, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong from pypy.annotation.builtin import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.lltypesystem import rffi @@ -526,11 +527,21 @@ return rffi.cast(rffi.VOIDP, v) res = self.interpret(llfn, [r_ulonglong(0)]) assert res == lltype.nullptr(rffi.VOIDP.TO) + # def llfn(v): return rffi.cast(rffi.LONGLONG, v) res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) assert res == 0 - assert isinstance(res, r_longlong) + if r_longlong is not r_int: + assert isinstance(res, r_longlong) + else: + assert isinstance(res, int) + # + def llfn(v): + return rffi.cast(rffi.ULONGLONG, v) + res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) + assert res == 0 + assert isinstance(res, r_ulonglong) class TestOOtype(BaseTestRbuiltin, OORtypeMixin): 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 Thu Mar 25 19:29:52 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import rdict, rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.objectmodel import r_dict -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong import py py.log.setconsumer("rtyper", py.log.STDOUT) @@ -567,6 +567,8 @@ def test_dict_of_r_uint(self): for r_t in [r_uint, r_longlong, r_ulonglong]: + if r_t is r_int: + continue # for 64-bit platforms: skip r_longlong d = {r_t(2): 3, r_t(4): 5} def fn(x, y): d[r_t(x)] = 123 Modified: pypy/trunk/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/trunk/pypy/rpython/test/test_rint.py (original) +++ pypy/trunk/pypy/rpython/test/test_rint.py Thu Mar 25 19:29:52 2010 @@ -110,10 +110,10 @@ def f(i): return str(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert self.ll_to_string(res) == '0' - res = self.interpret(f, [r_longlong(413974738222117)]) + res = self.interpret(f, [int64(413974738222117)]) assert self.ll_to_string(res) == '413974738222117' def test_unsigned(self): @@ -135,7 +135,7 @@ f._annspecialcase_ = "specialize:argtype(0)" def g(n): if n > 0: - return f(r_longlong(0)) + return f(int64(0)) else: return f(0) res = self.interpret(g, [0]) @@ -147,7 +147,7 @@ def test_downcast_int(self): def f(i): return int(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert res == 0 def test_isinstance_vs_int_types(self): 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 Mar 25 19:29:52 2010 @@ -299,11 +299,16 @@ fieldoffsets.append(offset) seen[cell] = True + allfields = tuple(['c_' + name for name, _ in fields]) + padfields = tuple(padfields) name = self.name + padding_drop = PaddingDrop(name, allfields, padfields, + config_result.CConfig._compilation_info_) hints = {'align': info['align'], 'size': info['size'], 'fieldoffsets': tuple(fieldoffsets), - 'padding': tuple(padfields)} + 'padding': padfields, + 'get_padding_drop': padding_drop} if name.startswith('struct '): name = name[7:] else: @@ -477,6 +482,89 @@ return info['size'] # ____________________________________________________________ + +class PaddingDrop(object): + # Compute (lazily) the padding_drop for a structure. + # See test_generate_padding for more information. + cache = None + + def __init__(self, name, allfields, padfields, eci): + self.name = name + self.allfields = allfields + self.padfields = padfields + self.eci = eci + + def __call__(self, types): + if self.cache is None: + self.compute_now(types) + return self.cache + + def compute_now(self, types): + # Some simplifying assumptions there. We assume that all fields + # are either integers or pointers, so can be written in C as '0'. + # We also assume that the C backend gives us in 'types' a dictionary + # mapping non-padding field names to their C type (without '@'). + drops = [] + staticfields = [] + consecutive_pads = [] + for fieldname in self.allfields: + if fieldname in self.padfields: + consecutive_pads.append(fieldname) + continue + staticfields.append(types[fieldname]) + if consecutive_pads: + # In that case we have to ask: how many of these pads are + # really needed? The correct answer might be between none + # and all of the pads listed in 'consecutive_pads'. + for i in range(len(consecutive_pads)+1): + class CConfig: + _compilation_info_ = self.eci + FIELDLOOKUP = _PaddingDropFieldLookup(self.name, + staticfields, + fieldname) + try: + got = configure(CConfig)['FIELDLOOKUP'] + if got == 1: + break # found + except CompilationError: + pass + staticfields.insert(-1, None) + else: + raise Exception("could not determine the detailed field" + " layout of %r" % (self.name,)) + # succeeded with 'i' pads. Drop all pads beyond that. + drops += consecutive_pads[i:] + consecutive_pads = [] + drops += consecutive_pads # drop the final pads too + self.cache = drops + +class _PaddingDropFieldLookup(CConfigEntry): + def __init__(self, name, staticfields, fieldname): + self.name = name + self.staticfields = staticfields + self.fieldname = fieldname + + def prepare_code(self): + yield 'typedef %s platcheck_t;' % (self.name,) + yield 'static platcheck_t s = {' + for i, type in enumerate(self.staticfields): + if i == len(self.staticfields)-1: + value = -1 + else: + value = 0 + if type: + yield '\t(%s)%s,' % (type, value) + else: + yield '\t%s,' % (value,) + yield '};' + fieldname = self.fieldname + assert fieldname.startswith('c_') + yield 'dump("fieldlookup", s.%s != 0);' % (fieldname[2:],) + + def build_result(self, info, config_result): + return info['fieldlookup'] + +# ____________________________________________________________ # # internal helpers Modified: pypy/trunk/pypy/rpython/tool/rfficache.py ============================================================================== --- pypy/trunk/pypy/rpython/tool/rfficache.py (original) +++ pypy/trunk/pypy/rpython/tool/rfficache.py Thu Mar 25 19:29:52 2010 @@ -13,7 +13,7 @@ from pypy.tool.gcc_cache import build_executable_cache def ask_gcc(question, add_source=""): - includes = ['stdlib.h', 'sys/types.h'] + includes = ['stdlib.h', 'stdio.h', 'sys/types.h'] include_string = "\n".join(["#include <%s>" % i for i in includes]) c_source = py.code.Source(''' // includes @@ -34,8 +34,8 @@ return build_executable_cache([c_file], eci) def sizeof_c_type(c_typename, **kwds): - question = 'printf("sizeof %s=%%d", sizeof(%s));' % (c_typename, - c_typename) + question = 'printf("sizeof %s=%%ld", (long)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]) Modified: pypy/trunk/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/trunk/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/trunk/pypy/rpython/tool/test/test_rffi_platform.py Thu Mar 25 19:29:52 2010 @@ -256,3 +256,104 @@ library_dirs = [str(tmpdir)] ) rffi_platform.verify_eci(eci) + +def test_generate_padding(): + # 'padding_drop' is a bit strange, but is what we need to write C code + # that defines prebuilt structures of that type. Normally, the C + # backend would generate '0' entries for every field c__pad#. That's + # usually much more than the number of real fields in the real structure + # definition. So 'padding_drop' allows a quick fix: it lists fields + # that should be ignored by the C backend. It should only be used in + # that situation because it lists some of the c__pad# fields a bit + # randomly -- to the effect that writing '0' for the other fields gives + # the right amount of '0's. + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad0'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == [] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + char c3; /* _pad1 */ + /* _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + /* _pad0 */ + short s1; /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + char c3; /* _pad3 */ + /* _pad4 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2', + 'c__pad3', 'c__pad4') + d = {'c_c1': 'char', 'c_i1': 'int', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2', 'c__pad4'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + long l2; /* some number of _pads */ + } foobar_t; + """, [("c1", lltype.Signed)]) + padding = list(S._hints['padding']) + d = {'c_c1': 'char'} + assert S._hints['get_padding_drop'](d) == padding Modified: pypy/trunk/pypy/translator/c/genc.py ============================================================================== --- pypy/trunk/pypy/translator/c/genc.py (original) +++ pypy/trunk/pypy/translator/c/genc.py Thu Mar 25 19:29:52 2010 @@ -167,16 +167,19 @@ have___thread = None + def merge_eci(self, *ecis): + self.eci = self.eci.merge(*ecis) + def collect_compilation_info(self, db): # we need a concrete gcpolicy to do this - self.eci = self.eci.merge(db.gcpolicy.compilation_info()) + self.merge_eci(db.gcpolicy.compilation_info()) all = [] for node in self.db.globalcontainers(): eci = getattr(node, 'compilation_info', None) if eci: all.append(eci) - self.eci = self.eci.merge(*all) + self.merge_eci(*all) def get_gcpolicyclass(self): if self.gcpolicy is None: Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Thu Mar 25 19:29:52 2010 @@ -37,6 +37,8 @@ class StructDefNode: typetag = 'struct' + extra_union_for_varlength = True + def __init__(self, db, STRUCT, varlength=1): self.db = db self.STRUCT = STRUCT @@ -82,7 +84,8 @@ self.fields = [] db = self.db STRUCT = self.STRUCT - varlength = self.varlength + if self.varlength != 1: + self.normalizedtypename = db.gettype(STRUCT, who_asks=self) if needs_gcheader(self.STRUCT): for fname, T in db.gcpolicy.struct_gcheader_definition(self): self.fields.append((fname, db.gettype(T, who_asks=self))) @@ -151,6 +154,12 @@ if is_empty: yield '\t' + 'char _dummy; /* this struct is empty */' yield '};' + if self.varlength != 1: + assert self.typetag == 'struct' + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_field): for name in self.fieldnames: @@ -162,6 +171,7 @@ def debug_offsets(self): # generate number exprs giving the offset of the elements in the struct + assert self.varlength == 1 for name in self.fieldnames: FIELD_T = self.c_struct_field_type(name) if FIELD_T is Void: @@ -178,15 +188,15 @@ class ArrayDefNode: typetag = 'struct' + extra_union_for_varlength = True def __init__(self, db, ARRAY, varlength=1): self.db = db self.ARRAY = ARRAY self.LLTYPE = ARRAY - original_varlength = varlength self.gcfields = [] self.varlength = varlength - if original_varlength == 1: + if varlength == 1: basename = 'array' with_number = True else: @@ -204,6 +214,8 @@ db = self.db ARRAY = self.ARRAY self.gcinfo # force it to be computed + if self.varlength != 1: + self.normalizedtypename = db.gettype(ARRAY, who_asks=self) if needs_gcheader(ARRAY): for fname, T in db.gcpolicy.array_gcheader_definition(self): self.gcfields.append((fname, db.gettype(T, who_asks=self))) @@ -251,8 +263,14 @@ line = 'char _dummy; ' + line yield '\t' + line yield '};' + if self.varlength != 1: + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_item): + assert self.varlength == 1 ARRAY = self.ARRAY # we need a unique name for this C variable, or at least one that does # not collide with the expression in 'prefix' @@ -279,6 +297,7 @@ def debug_offsets(self): # generate three offsets for debugging inspection + assert self.varlength == 1 if not self.ARRAY._hints.get('nolength', False): yield 'offsetof(struct %s, length)' % (self.name,) else: @@ -299,6 +318,7 @@ gcinfo = None name = None forward_decl = None + extra_union_for_varlength = False def __init__(self, db, ARRAY, varlength=1): self.db = db @@ -349,6 +369,7 @@ gcinfo = None name = None typetag = 'struct' + extra_union_for_varlength = False def __init__(self, db, FIXEDARRAY): self.db = db @@ -461,28 +482,42 @@ parentnode = db.getcontainernode(parent) defnode = db.gettypedefnode(parentnode.T) self.name = defnode.access_expr(parentnode.name, parentindex) - self.ptrname = '(&%s)' % self.name if self.typename != self.implementationtypename: - ptrtypename = db.gettype(Ptr(T)) - self.ptrname = '((%s)(void*)%s)' % (cdecl(ptrtypename, ''), - self.ptrname) + if db.gettypedefnode(T).extra_union_for_varlength: + self.name += '.b' + self.ptrname = '(&%s)' % self.name def is_thread_local(self): return hasattr(self.T, "_hints") and self.T._hints.get('thread_local') + def get_declaration(self): + if self.name[-2:] == '.b': + # xxx fish fish + assert self.implementationtypename.startswith('struct ') + assert self.implementationtypename.endswith(' @') + uniontypename = 'union %su @' % self.implementationtypename[7:-2] + return uniontypename, self.name[:-2] + else: + return self.implementationtypename, self.name + def forward_declaration(self): if llgroup.member_of_group(self.obj): return + type, name = self.get_declaration() yield '%s;' % ( - forward_cdecl(self.implementationtypename, - self.name, self.db.standalone, self.is_thread_local())) + forward_cdecl(type, name, self.db.standalone, + self.is_thread_local())) def implementation(self): if llgroup.member_of_group(self.obj): return [] lines = list(self.initializationexpr()) + type, name = self.get_declaration() + if name != self.name: + lines[0] = '{ ' + lines[0] # extra braces around the 'a' part + lines[-1] += ' }' # of the union lines[0] = '%s = %s' % ( - cdecl(self.implementationtypename, self.name, self.is_thread_local()), + cdecl(type, name, self.is_thread_local()), lines[0]) lines[-1] += ';' return lines @@ -536,7 +571,19 @@ if hasattr(self.T, "_hints") and self.T._hints.get('union'): data = data[0:1] + if 'get_padding_drop' in self.T._hints: + d = {} + for name, _ in data: + T = defnode.c_struct_field_type(name) + typename = self.db.gettype(T) + d[name] = cdecl(typename, '') + padding_drop = self.T._hints['get_padding_drop'](d) + else: + padding_drop = [] + for name, value in data: + if name in padding_drop: + continue c_expr = defnode.access_expr(self.name, name) lines = generic_initializationexpr(self.db, value, c_expr, decoration + name) @@ -560,6 +607,7 @@ return 'struct _hashT_%s @' % self.name def forward_declaration(self): + assert self.typename == self.implementationtypename # no array part hash_typename = self.get_hash_typename() hash_offset = self.db.gctransformer.get_hash_offset(self.T) yield '%s {' % cdecl(hash_typename, '') @@ -675,6 +723,7 @@ return 1 # not variable-sized! def initializationexpr(self, decoration=''): + assert self.typename == self.implementationtypename # not var-sized is_empty = True yield '{' # _names == ['item0', 'item1', ...] Modified: pypy/trunk/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/trunk/pypy/translator/c/test/test_lltyped.py Thu Mar 25 19:29:52 2010 @@ -782,3 +782,48 @@ fn = self.getcompiled(f, []) res = fn() assert res == 42 + + def test_padding_in_prebuilt_struct(self): + from pypy.rpython.lltypesystem import rffi + from pypy.rpython.tool import rffi_platform + eci = rffi_platform.eci_from_header(""" + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + char c2; /* followed by 3 bytes of padding */ + int i2; + char c3; /* followed by 3 or 7 bytes of padding */ + long l3; + char c4; + } foobar_t; + """) + class CConfig: + _compilation_info_ = eci + STRUCT = rffi_platform.Struct("foobar_t", + [("c1", Signed), + ("s1", Signed), + ("l3", Signed)]) + S = rffi_platform.configure(CConfig)['STRUCT'] + assert 'get_padding_drop' in S._hints + s1 = malloc(S, immortal=True) + s1.c_c1 = rffi.cast(S.c_c1, -12) + s1.c_s1 = rffi.cast(S.c_s1, -7843) + s1.c_l3 = -98765432 + s2 = malloc(S, immortal=True) + s2.c_c1 = rffi.cast(S.c_c1, -123) + s2.c_s1 = rffi.cast(S.c_s1, -789) + s2.c_l3 = -9999999 + # + def f(n): + if n > 5: + s = s1 + else: + s = s2 + return s.c_l3 + # + self.include_also_eci = eci + fn = self.getcompiled(f, [int]) + res = fn(10) + assert res == -98765432 + res = fn(1) + assert res == -9999999 Modified: pypy/trunk/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/trunk/pypy/translator/c/test/test_newgc.py (original) +++ pypy/trunk/pypy/translator/c/test/test_newgc.py Thu Mar 25 19:29:52 2010 @@ -653,8 +653,8 @@ to_sort[2] = 1 to_sort[3] = 2 qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort)) - qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) qsort.push_arg(rffi.cast(rffi.SIZE_T, 4)) + qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) 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] 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 Mar 25 19:29:52 2010 @@ -28,6 +28,8 @@ def compilefunc(self, t, func): from pypy.translator.c import genc self.builder = builder = genc.CExtModuleBuilder(t, func, config=t.config) + if hasattr(self, 'include_also_eci'): + builder.merge_eci(self.include_also_eci) builder.generate_source() builder.compile() return builder.get_entry_point() From arigo at codespeak.net Thu Mar 25 19:30:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 19:30:06 +0100 (CET) Subject: [pypy-svn] r72844 - pypy/branch/fix-64 Message-ID: <20100325183006.71AA0282BE5@codespeak.net> Author: arigo Date: Thu Mar 25 19:30:05 2010 New Revision: 72844 Removed: pypy/branch/fix-64/ Log: Remove merged branch. From arigo at codespeak.net Thu Mar 25 19:57:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 19:57:47 +0100 (CET) Subject: [pypy-svn] r72845 - pypy/trunk/pypy/translator/goal Message-ID: <20100325185747.417DA282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 19:57:44 2010 New Revision: 72845 Modified: pypy/trunk/pypy/translator/goal/translate.py Log: Always remove pypy/_cache at the very start of translate.py. Probably avoids surprizes and misunderstandings when the _cache gets out of date because e.g. you installed a new system header. Modified: pypy/trunk/pypy/translator/goal/translate.py ============================================================================== --- pypy/trunk/pypy/translator/goal/translate.py (original) +++ pypy/trunk/pypy/translator/goal/translate.py Thu Mar 25 19:57:44 2010 @@ -7,6 +7,12 @@ import sys, os, new import autopath +import py +# clean up early pypy/_cache +try: + py.path.local(autopath.pypydir).join('_cache').remove() +except py.error: + pass from pypy.config.config import to_optparse, OptionDescription, BoolOption, \ ArbitraryOption, StrOption, IntOption, Config, \ @@ -82,7 +88,6 @@ 'translation.debug': False, } -import py # we want 2.4 expand_default functionality import optparse from pypy.tool.ansi_print import ansi_log From arigo at codespeak.net Thu Mar 25 20:19:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 20:19:18 +0100 (CET) Subject: [pypy-svn] r72846 - in pypy/trunk/pypy/rpython: lltypesystem tool Message-ID: <20100325191918.86787282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 20:19:17 2010 New Revision: 72846 Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py pypy/trunk/pypy/rpython/tool/rfficache.py Log: Whack (maybe unneeded) to have one instead of about 15 calls to the compiler to fint out the basic size of primitive integer types. Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py Thu Mar 25 20:19:17 2010 @@ -356,10 +356,9 @@ MODE_T = lltype.Signed PID_T = lltype.Signed -def setup(): - """ creates necessary c-level types - """ - result = [] +def populate_inttypes(): + names = [] + populatelist = [] for name in TYPES: c_name = name if name.startswith('unsigned'): @@ -368,7 +367,18 @@ else: signed = (name != 'size_t') name = name.replace(' ', '') - tp = platform.inttype(name.upper(), c_name, signed) + names.append(name) + populatelist.append((name.upper(), c_name, signed)) + platform.populate_inttypes(populatelist) + return names + +def setup(): + """ creates necessary c-level types + """ + names = populate_inttypes() + result = [] + for name in names: + tp = platform.types[name.upper()] globals()['r_' + name] = platform.numbertype_to_rclass[tp] globals()[name.upper()] = tp tpp = lltype.Ptr(lltype.Array(tp, hints={'nolength': True})) Modified: pypy/trunk/pypy/rpython/tool/rfficache.py ============================================================================== --- pypy/trunk/pypy/rpython/tool/rfficache.py (original) +++ pypy/trunk/pypy/rpython/tool/rfficache.py Thu Mar 25 20:19:17 2010 @@ -34,12 +34,22 @@ return build_executable_cache([c_file], eci) def sizeof_c_type(c_typename, **kwds): - question = 'printf("sizeof %s=%%ld", (long)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]) + return sizeof_c_types([c_typename], **kwds)[0] + +def sizeof_c_types(typenames_c, **kwds): + lines = ['printf("sizeof %s=%%ld\\n", (long)sizeof(%s));' % (c_typename, + c_typename) + for c_typename in typenames_c] + question = '\n\t'.join(lines) + answer = ask_gcc(question, **kwds) + lines = answer.splitlines() + assert len(lines) == len(typenames_c) + result = [] + for line, c_typename in zip(lines, typenames_c): + answer = line.split('=') + assert answer[0] == "sizeof " + c_typename + result.append(int(answer[1])) + return result class Platform: def __init__(self): @@ -50,11 +60,28 @@ try: return self.types[name] except KeyError: - bits = sizeof_c_type(c_name, **kwds) * 8 - inttype = rarithmetic.build_int('r_' + name, signed, bits) - tp = lltype.build_number(name, inttype) - self.numbertype_to_rclass[tp] = inttype - self.types[name] = tp - return tp + size = sizeof_c_type(c_name, **kwds) + return self._make_type(name, signed, size) + + def _make_type(self, name, signed, size): + inttype = rarithmetic.build_int('r_' + name, signed, size*8) + tp = lltype.build_number(name, inttype) + self.numbertype_to_rclass[tp] = inttype + self.types[name] = tp + return tp + + def populate_inttypes(self, list, **kwds): + """'list' is a list of (name, c_name, signed).""" + missing = [] + names_c = [] + for name, c_name, signed in list: + if name not in self.types: + missing.append((name, signed)) + names_c.append(c_name) + if names_c: + sizes = sizeof_c_types(names_c, **kwds) + assert len(sizes) == len(missing) + for (name, signed), size in zip(missing, sizes): + self._make_type(name, signed, size) platform = Platform() From fijal at codespeak.net Thu Mar 25 21:06:19 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 21:06:19 +0100 (CET) Subject: [pypy-svn] r72847 - in pypy/branch/kill-asm-call/pypy/jit/backend/llsupport: . test Message-ID: <20100325200619.F281D282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 21:05:55 2010 New Revision: 72847 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Log: Finish the test and make the test pass Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Thu Mar 25 21:05:55 2010 @@ -1,8 +1,9 @@ import py -from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import lltype, rffi, llmemory from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat +from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances @@ -217,36 +218,38 @@ return self.call_stub def create_call_stub(self, FUNC): - def no_result(arg): - return None - def process(no, c): if c == 'i': - return 'lltype.cast_primitive(FUNC.ARGS[%d], arg[%d].getint())' % (no, no) + return 'lltype.cast_primitive(FUNC.ARGS[%d], args[%d].getint())' % (no - 1, no) elif c == 'f': return 'args[%d].getfloat()' % (no,) elif c == 'r': - return 'arg[%d].getptr(FUNC.ARGS[%d])' % (no, no) + return 'args[%d].getref(FUNC.ARGS[%d])' % (no, no - 1) else: raise Exception("Unknown type %s for type %s" % (c, TP)) - + + args = ", ".join([process(i + 1, c) for i, c in + enumerate(self.arg_classes)]) + if self.returns_a_pointer(): - restype = 'BoxPtr' + result = 'history.BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, res))' elif self.returns_a_float(): - restype = 'BoxFloat' + result = 'history.BoxFloat(res)' elif self.returns_a_void(): - restype = 'no_result' + result = 'None' else: - restype = 'BoxInt' - args = ", ".join([process(i, c) for i, c in - enumerate(self.arg_classes)]) + result = 'history.BoxInt(lltype.cast_primitive(lltype.Signed, res))' source = py.code.Source(""" - def call_stub(callable, args): - ll_callable = lltype.cast_opaque_ptr(FUNC, callable) - return %(restype)s(ll_callable(%(args)s)) + def call_stub(args): + ll_callable = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) + res = ll_callable(%(args)s) + return %(result)s """ % locals()) d = locals().copy() d['lltype'] = lltype + d['rffi'] = rffi + d['history'] = history + d['llmemory'] = llmemory exec source.compile() in d self.call_stub = d['call_stub'] Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Thu Mar 25 21:05:55 2010 @@ -238,7 +238,24 @@ return 'c' call_stub = descr1.get_call_stub() - fnptr = llhelper(lltype.FuncType(ARGS, RES), f) + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) - res = call_stub(fnptr, [BoxInt(1), BoxInt(2)]) + res = call_stub([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxInt(1), BoxInt(2)]) assert res.getint() == ord('c') + + ARRAY = lltype.GcArray(lltype.Signed) + ARGS = [lltype.Float, lltype.Ptr(ARRAY)] + RES = lltype.Float + + def f(a, b): + return float(b[0]) + a + + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + descr2 = get_call_descr(c0, ARGS, RES) + a = lltype.malloc(ARRAY, 3) + opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) + a[0] = 1 + res = descr2.get_call_stub()([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxFloat(3.5), BoxPtr(opaquea)]) + assert res.getfloat() == 4.5 From fijal at codespeak.net Thu Mar 25 21:09:15 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 21:09:15 +0100 (CET) Subject: [pypy-svn] r72848 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100325200915.BBC2C282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 21:08:45 2010 New Revision: 72848 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Log: This makes test_runner pass - the exception handling is not correct though Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Thu Mar 25 21:08:45 2010 @@ -474,19 +474,8 @@ if not we_are_translated(): assert (list(calldescr.arg_classes) == [arg.type for arg in args[1:]]) - loop_token = calldescr.get_token_for_call(self) - set_future_values(self, args) - self.execute_token(loop_token) - # Note: if an exception is set, the rest of the code does a bit of - # nonsense but nothing wrong (the return value should be ignored) - if calldescr.returns_a_pointer(): - return BoxPtr(self.get_latest_value_ref(0)) - elif calldescr.returns_a_float(): - return BoxFloat(self.get_latest_value_float(0)) - elif calldescr.get_result_size(self.translate_support_code) > 0: - return BoxInt(self.get_latest_value_int(0)) - else: - return None + callstub = calldescr.get_call_stub() + return callstub(args) def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) From arigo at codespeak.net Thu Mar 25 21:26:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 21:26:15 +0100 (CET) Subject: [pypy-svn] r72849 - pypy/build/bot2/codespeak-html Message-ID: <20100325202615.41E11282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 21:26:10 2010 New Revision: 72849 Modified: pypy/build/bot2/codespeak-html/robots.txt Log: Disallow /grid view too. Doesn't make sense to allow it, and it's quite a slow page too. Modified: pypy/build/bot2/codespeak-html/robots.txt ============================================================================== --- pypy/build/bot2/codespeak-html/robots.txt (original) +++ pypy/build/bot2/codespeak-html/robots.txt Thu Mar 25 21:26:10 2010 @@ -8,3 +8,4 @@ Disallow: /one_line_per_build Disallow: /one_box_per_builder Disallow: /xmlrpc +Disallow: /grid From arigo at codespeak.net Thu Mar 25 21:27:14 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 21:27:14 +0100 (CET) Subject: [pypy-svn] r72850 - pypy/build/bot2/pypybuildbot Message-ID: <20100325202714.52F23282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 21:27:12 2010 New Revision: 72850 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Rename the category. (This change was already on the buildmaster for a few days before.) Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Thu Mar 25 21:27:12 2010 @@ -156,7 +156,7 @@ "slavenames": ["tannit64"], "builddir": LINUX64, "factory": pypyOwnTestFactory, - "category": 'own' + "category": 'own64' }, {"name": MACOSX32, "slavenames": ["minime"], From fijal at codespeak.net Thu Mar 25 22:11:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 22:11:22 +0100 (CET) Subject: [pypy-svn] r72851 - pypy/benchmarks Message-ID: <20100325211122.9ED80282BED@codespeak.net> Author: fijal Date: Thu Mar 25 22:11:20 2010 New Revision: 72851 Modified: pypy/benchmarks/runner.py Log: Use different way of telling "we're on psyco" Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Thu Mar 25 22:11:20 2010 @@ -40,8 +40,9 @@ name = "pypy-c-jit" optionsname = "gc=hybrid" if "psyco.sh" in pypy_c_path: - name = "python-psyco-profile" - optionsname = "default" + name = "cpython" + optionsname = "psyco-profile" + revision = 262 if force_host is not None: host = force_host else: From xoraxax at codespeak.net Thu Mar 25 22:24:26 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 22:24:26 +0100 (CET) Subject: [pypy-svn] r72852 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100325212426.3D874282BED@codespeak.net> Author: xoraxax Date: Thu Mar 25 22:24:24 2010 New Revision: 72852 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Log: Two skipped failing tests for amaury. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Thu Mar 25 22:24:24 2010 @@ -1,3 +1,5 @@ +import py + from pypy.module.cpyext.test.test_api import BaseApiTest class TestObject(BaseApiTest): @@ -35,6 +37,7 @@ api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(5)) assert not api.PyErr_Occurred() assert x.test == 5 + py.test.skip("Fails in the next line, amaury?") assert api.PyObject_HasAttr(space.wrap(x), space.wrap('test')) api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(10)) assert x.test == 10 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Thu Mar 25 22:24:24 2010 @@ -1,7 +1,10 @@ +import py + from pypy.module.cpyext.test.test_api import BaseApiTest class TestTupleObject(BaseApiTest): def test_tupleobject(self, space, api): + py.test.skip("Needs API refactoring, done by amaury") assert not api.PyTuple_Check(space.w_None) assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1 api.PyErr_Clear() From xoraxax at codespeak.net Thu Mar 25 22:24:42 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 22:24:42 +0100 (CET) Subject: [pypy-svn] r72853 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325212442.89314282BED@codespeak.net> Author: xoraxax Date: Thu Mar 25 22:24:41 2010 New Revision: 72853 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py Log: Remove comment. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Thu Mar 25 22:24:41 2010 @@ -17,7 +17,6 @@ @cpython_api([rffi.VOIDP_real], lltype.Void) def PyObject_Del(space, obj): - # XXX cast object according to the basesize in pto lltype.free(obj, flavor='raw') @cpython_api([PyObject], lltype.Void) From fijal at codespeak.net Thu Mar 25 22:25:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 22:25:06 +0100 (CET) Subject: [pypy-svn] r72854 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100325212506.E12CC282BED@codespeak.net> Author: fijal Date: Thu Mar 25 22:25:05 2010 New Revision: 72854 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Log: Pass rtyper arg and use maybe_on_top_of_llinterp Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Thu Mar 25 22:25:05 2010 @@ -3,7 +3,7 @@ from pypy.jit.backend.llsupport import symbolic from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat -from pypy.jit.metainterp import history +from pypy.jit.metainterp import history, support from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances @@ -13,8 +13,9 @@ class GcCache(object): - def __init__(self, translate_support_code): + def __init__(self, translate_support_code, rtyper=None): self.translate_support_code = translate_support_code + self.rtyper = rtyper self._cache_size = {} self._cache_field = {} self._cache_array = {} @@ -217,7 +218,7 @@ def get_call_stub(self): return self.call_stub - def create_call_stub(self, FUNC): + def create_call_stub(self, rtyper, FUNC): def process(no, c): if c == 'i': return 'lltype.cast_primitive(FUNC.ARGS[%d], args[%d].getint())' % (no - 1, no) @@ -242,14 +243,11 @@ source = py.code.Source(""" def call_stub(args): ll_callable = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) - res = ll_callable(%(args)s) + res = support.maybe_on_top_of_llinterp(rtyper, ll_callable)(%(args)s) return %(result)s """ % locals()) d = locals().copy() - d['lltype'] = lltype - d['rffi'] = rffi - d['history'] = history - d['llmemory'] = llmemory + d.update(globals()) exec source.compile() in d self.call_stub = d['call_stub'] @@ -297,7 +295,7 @@ return cache[key] except KeyError: calldescr = cls(arg_classes, extrainfo) - calldescr.create_call_stub(lltype.FuncType(ARGS, RESULT)) + calldescr.create_call_stub(gccache.rtyper, lltype.FuncType(ARGS, RESULT)) cache[key] = calldescr return calldescr Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Thu Mar 25 22:25:05 2010 @@ -475,7 +475,14 @@ assert (list(calldescr.arg_classes) == [arg.type for arg in args[1:]]) callstub = calldescr.get_call_stub() - return callstub(args) + try: + return callstub(args) + except Exception, e: + if we_are_translated(): + xxx + else: + import pdb + pdb.set_trace() def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) From xoraxax at codespeak.net Thu Mar 25 22:26:26 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 22:26:26 +0100 (CET) Subject: [pypy-svn] r72855 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100325212626.5F493282BED@codespeak.net> Author: xoraxax Date: Thu Mar 25 22:26:24 2010 New Revision: 72855 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Implement borrowing. We need two new dicts for that. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 22:26:24 2010 @@ -260,12 +260,19 @@ py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) py_obj = rffi.cast(PyObject, py_obj) if DEBUG_REFCOUNT: - print "MAKREF", py_obj, w_obj + print >>sys.stderr, "MAKREF", py_obj, w_obj state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj + if borrowed and ptr not in state.borrowed_objects: + state.borrowed_objects[ptr] = None elif not steal: - Py_INCREF(space, py_obj) - # XXX borrowed references? + if borrowed: + py_obj_addr = ctypes.addressof(py_obj._obj._storage) + if py_obj_addr not in state.borrowed_objects: + Py_INCREF(space, py_obj) + state.borrowed_objects[py_obj_addr] = None + else: + Py_INCREF(space, py_obj) return py_obj def force_string(space, ref): @@ -289,19 +296,23 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: - if space.is_w(from_ref(space, ref.c_obj_type), space.w_str): + ref_type = ref.c_obj_type + if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str): return force_string(space, ref) else: raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) return obj -def clear_memory(space): - from pypy.module.cpyext.macros import Py_DECREF + + at cpython_api([PyObject, PyObject], lltype.Void, external=False) +def add_borrowed_object(space, container, obj): state = space.fromcache(State) - while state.py_objects_r2w: - key = state.py_objects_r2w.keys()[0] - Py_DECREF(space, key) - state.reset() + container_ptr = ctypes.addressof(container._obj._storage) + borrowees = state.borrow_mapping.get(container_ptr) + if borrowees is None: + state.borrow_mapping[container_ptr] = borrowees = {} + obj_ptr = ctypes.addressof(obj._obj._storage) + borrowees[obj_ptr] = None def general_check(space, w_obj, w_type): @@ -517,6 +528,9 @@ if FT.RESULT is PyObject: ret = from_ref(space, result) if result: + # The object reference returned from a C function + # that is called from Python must be an owned reference + # - ownership is transferred from the function to its caller. Py_DECREF(space, result) # Check for exception consistency Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 22:26:24 2010 @@ -1,4 +1,5 @@ import ctypes +import sys from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref @@ -12,19 +13,31 @@ from pypy.module.cpyext.typeobject import string_dealloc obj.c_obj_refcnt -= 1 if DEBUG_REFCOUNT: - print "DECREF", obj, obj.c_obj_refcnt + print >>sys.stderr, "DECREF", obj, obj.c_obj_refcnt if obj.c_obj_refcnt == 0: state = space.fromcache(State) ptr = ctypes.addressof(obj._obj._storage) if ptr not in state.py_objects_r2w and \ space.is_w(from_ref(space, obj.c_obj_type), space.w_str): # this is a half-allocated string, lets call the deallocator - # directly - string_dealloc(space, obj) + # without modifying the r2w/w2r dicts + _Py_Dealloc(space, obj) else: w_obj = state.py_objects_r2w.pop(ptr) _Py_Dealloc(space, obj) del state.py_objects_w2r[w_obj] + if ptr in state.borrow_mapping: + for containee in state.borrow_mapping[ptr]: + w_containee = state.py_objects_r2w.get(containee) + if w_containee is not None: + containee = state.py_objects_w2r[w_containee] + Py_DECREF(space, w_containee) + containee_ptr = ctypes.addressof(containee._obj._storage) + try: + del state.borrowed_objects[containee_ptr] + except KeyError: + pass + del state.borrow_mapping[ptr] else: assert obj.c_obj_refcnt > 0 @@ -32,7 +45,7 @@ def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 if DEBUG_REFCOUNT: - print "INCREF", obj, obj.c_obj_refcnt + print >>sys.stderr, "INCREF", obj, obj.c_obj_refcnt @cpython_api([PyObject], lltype.Void) def Py_XDECREF(space, obj): @@ -45,7 +58,7 @@ state = space.fromcache(State) pto = obj.c_obj_type pto = rffi.cast(PyTypeObjectPtr, pto) - print "Calling dealloc slot of", obj, \ + print >>sys.stderr, "Calling dealloc slot of", obj, \ "'s type which is", rffi.charp2str(pto.c_tp_name) generic_cpy_call(space, pto.c_tp_dealloc, obj, decref_args=False) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Thu Mar 25 22:26:24 2010 @@ -2,13 +2,17 @@ from pypy.lib.identity_dict import identity_dict from pypy.interpreter.error import OperationError + class State: def __init__(self, space): + self.space = space self.reset() def reset(self): - self.py_objects_w2r = identity_dict() # w_obj -> raw PyObject - self.py_objects_r2w = {} # addr of raw PyObject -> w_obj + self.py_objects_w2r = identity_dict() # { w_obj -> raw PyObject } + self.py_objects_r2w = {} # { addr of raw PyObject -> w_obj } + self.borrow_mapping = {} # { addr of container -> { addr of containee -> None } } + self.borrowed_objects = {} # { addr of containee -> None } self.exc_type = None self.exc_value = None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Thu Mar 25 22:26:24 2010 @@ -11,6 +11,7 @@ from pypy.module.cpyext.state import State from pypy.module.cpyext.macros import Py_DECREF from pypy.translator.goal import autopath +from pypy.lib.identity_dict import identity_dict @api.cpython_api([], api.PyObject) def PyPy_Crash1(space): @@ -56,7 +57,6 @@ class AppTestCpythonExtensionBase: def setup_class(cls): cls.space = gettestobjspace(usemodules=['cpyext']) - cls.freeze_refcnts() def import_module(self, name, init=None, body=''): if init is not None: @@ -117,6 +117,7 @@ def setup_method(self, func): self.w_import_module = self.space.wrap(self.import_module) self.w_import_extension = self.space.wrap(self.import_extension) + self.freeze_refcnts() #self.check_and_print_leaks("Object %r leaked some time ago (refcount %i) -- Not executing test!") def teardown_method(self, func): @@ -128,29 +129,35 @@ Py_DECREF(self.space, w_mod) except OperationError: pass + state = self.space.fromcache(State) if self.check_and_print_leaks(): - assert False, "Test leaks object(s)." + assert False, "Test leaks or loses object(s)." - @classmethod - def freeze_refcnts(cls): - state = cls.space.fromcache(State) - cls.frozen_refcounts = {} + def freeze_refcnts(self): + state = self.space.fromcache(State) + self.frozen_refcounts = {} for w_obj, obj in state.py_objects_w2r.iteritems(): - cls.frozen_refcounts[w_obj] = obj.c_obj_refcnt + self.frozen_refcounts[w_obj] = obj.c_obj_refcnt + state.print_refcounts() def check_and_print_leaks(self): # check for sane refcnts leaking = False state = self.space.fromcache(State) - global_objects_w = set() + lost_objects_w = identity_dict() + lost_objects_w.update((key, None) for key in self.frozen_refcounts.keys()) for w_obj, obj in state.py_objects_w2r.iteritems(): base_refcnt = self.frozen_refcounts.get(w_obj) delta = obj.c_obj_refcnt if base_refcnt is not None: delta -= base_refcnt + lost_objects_w.pop(w_obj) if delta != 0: leaking = True print >>sys.stderr, "Leaking %r: %i references" % (w_obj, delta) + for w_obj in lost_objects_w: + print >>sys.stderr, "Lost object %r" % (w_obj, ) + leaking = True return leaking @@ -273,7 +280,9 @@ body = """ PyObject* foo_test(PyObject* self, PyObject *args) { - return PyTuple_GetItem(args, 0); + PyObject *t = PyTuple_GetItem(args, 0); + Py_INCREF(t); + return t; } static PyMethodDef methods[] = { { "test", foo_test, METH_VARARGS }, Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Thu Mar 25 22:26:24 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \ - general_check, CANNOT_FAIL + general_check, CANNOT_FAIL, add_borrowed_object from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.tupleobject import W_TupleObject @@ -29,4 +29,5 @@ PyErr_BadInternalCall(space) assert isinstance(w_t, W_TupleObject) w_obj = w_t.wrappeditems[pos] + add_borrowed_object(space, w_t, w_obj) return w_obj Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 22:26:24 2010 @@ -1,4 +1,5 @@ import ctypes +import sys from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void @@ -220,7 +221,7 @@ @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): - print "Dealloc of", obj + print >>sys.stderr, "Dealloc of", obj pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto From xoraxax at codespeak.net Thu Mar 25 22:28:32 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 22:28:32 +0100 (CET) Subject: [pypy-svn] r72856 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325212832.48412282BED@codespeak.net> Author: xoraxax Date: Thu Mar 25 22:28:30 2010 New Revision: 72856 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Update TODO file, remove XXX. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Thu Mar 25 22:28:30 2010 @@ -1,7 +1,5 @@ - Implement C API. - Complete the PyTypeObject initialization code. - - properly support "borrowed" references: the PyObject must be stored - somewhere - Use a WeakKeyDictionary to count how often a PyObject is allocated for a given wrapped object and use this to assess whether optimizations are useful Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Thu Mar 25 22:28:30 2010 @@ -20,7 +20,7 @@ PyErr_BadInternalCall(space) assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj - Py_DECREF(space, w_obj) # SetItem steals a reference! XXX this needs to go into the wrapper + Py_DECREF(space, w_obj) # SetItem steals a reference! return 0 @cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) From fijal at codespeak.net Thu Mar 25 22:38:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 22:38:04 +0100 (CET) Subject: [pypy-svn] r72857 - in pypy/branch/kill-asm-call/pypy/jit/backend/llsupport: . test Message-ID: <20100325213804.CA68E282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 22:38:02 2010 New Revision: 72857 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/gc.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_gc.py Log: Pass around rtyper as well Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/gc.py Thu Mar 25 22:38:02 2010 @@ -19,8 +19,8 @@ # ____________________________________________________________ class GcLLDescription(GcCache): - def __init__(self, gcdescr, translator=None): - GcCache.__init__(self, translator is not None) + def __init__(self, gcdescr, translator=None, rtyper=None): + GcCache.__init__(self, translator is not None, rtyper) self.gcdescr = gcdescr def _freeze_(self): return True @@ -41,8 +41,8 @@ moving_gc = False gcrootmap = None - def __init__(self, gcdescr, translator): - GcLLDescription.__init__(self, gcdescr, translator) + def __init__(self, gcdescr, translator, rtyper): + GcLLDescription.__init__(self, gcdescr, translator, rtyper) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() @@ -327,11 +327,11 @@ class GcLLDescr_framework(GcLLDescription): DEBUG = False # forced to True by x86/test/test_zrpy_gc.py - def __init__(self, gcdescr, translator, llop1=llop): + def __init__(self, gcdescr, translator, rtyper, llop1=llop): from pypy.rpython.memory.gctypelayout import _check_typeid from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.gctransform import framework - GcLLDescription.__init__(self, gcdescr, translator) + GcLLDescription.__init__(self, gcdescr, translator, rtyper) assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 @@ -611,7 +611,7 @@ # ____________________________________________________________ -def get_ll_description(gcdescr, translator=None): +def get_ll_description(gcdescr, translator=None, rtyper=None): # translator is None if translate_support_code is False. if gcdescr is not None: name = gcdescr.config.translation.gctransformer @@ -622,4 +622,4 @@ except KeyError: raise NotImplementedError("GC transformer %r not supported by " "the JIT backend" % (name,)) - return cls(gcdescr, translator) + return cls(gcdescr, translator, rtyper) Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Thu Mar 25 22:38:02 2010 @@ -31,7 +31,7 @@ translator = rtyper.annotator.translator else: translator = None - self.gc_ll_descr = get_ll_description(gcdescr, translator) + self.gc_ll_descr = get_ll_description(gcdescr, translator, rtyper) if translator and translator.config.translation.gcremovetypeptr: self.vtable_offset = None else: Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_gc.py Thu Mar 25 22:38:02 2010 @@ -9,7 +9,7 @@ def test_boehm(): - gc_ll_descr = GcLLDescr_boehm(None, None) + gc_ll_descr = GcLLDescr_boehm(None, None, None) # record = [] prev_funcptr_for_new = gc_ll_descr.funcptr_for_new @@ -167,7 +167,8 @@ gcdescr = get_description(config_) translator = FakeTranslator() llop1 = FakeLLOp() - gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), None, + llop1) gc_ll_descr.initialize() self.llop1 = llop1 self.gc_ll_descr = gc_ll_descr From xoraxax at codespeak.net Thu Mar 25 22:44:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 22:44:09 +0100 (CET) Subject: [pypy-svn] r72858 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325214409.E4683282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 25 22:44:08 2010 New Revision: 72858 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Do not use ctypes anymore for retrieval of the address. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Thu Mar 25 22:44:08 2010 @@ -22,6 +22,7 @@ Py_ssize_t = lltype.Signed +ADDR = lltype.Signed include_dir = py.path.local(autopath.pypydir) / 'module' / 'cpyext' / 'include' include_dirs = [ @@ -101,6 +102,8 @@ error = lltype.nullptr(PyObject.TO) elif restype is lltype.Void: error = CANNOT_FAIL + if type(error) is int: + error = rffi.cast(restype, error) def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed, error) @@ -267,7 +270,7 @@ state.borrowed_objects[ptr] = None elif not steal: if borrowed: - py_obj_addr = ctypes.addressof(py_obj._obj._storage) + py_obj_addr = rffi.cast(ADDR, py_obj) if py_obj_addr not in state.borrowed_objects: Py_INCREF(space, py_obj) state.borrowed_objects[py_obj_addr] = None @@ -292,7 +295,7 @@ if not ref: return None state = space.fromcache(State) - ptr = ctypes.addressof(ref._obj._storage) + ptr = rffi.cast(ADDR, ref) try: obj = state.py_objects_r2w[ptr] except KeyError: @@ -307,11 +310,11 @@ @cpython_api([PyObject, PyObject], lltype.Void, external=False) def add_borrowed_object(space, container, obj): state = space.fromcache(State) - container_ptr = ctypes.addressof(container._obj._storage) + container_ptr = rffi.cast(ADDR, container) borrowees = state.borrow_mapping.get(container_ptr) if borrowees is None: state.borrow_mapping[container_ptr] = borrowees = {} - obj_ptr = ctypes.addressof(obj._obj._storage) + obj_ptr = rffi.cast(ADDR, obj) borrowees[obj_ptr] = None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Thu Mar 25 22:44:08 2010 @@ -1,8 +1,8 @@ -import ctypes import sys from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ + ADDR from pypy.module.cpyext.state import State DEBUG_REFCOUNT = False @@ -16,7 +16,7 @@ print >>sys.stderr, "DECREF", obj, obj.c_obj_refcnt if obj.c_obj_refcnt == 0: state = space.fromcache(State) - ptr = ctypes.addressof(obj._obj._storage) + ptr = rffi.cast(ADDR, obj) if ptr not in state.py_objects_r2w and \ space.is_w(from_ref(space, obj.c_obj_type), space.w_str): # this is a half-allocated string, lets call the deallocator @@ -32,7 +32,7 @@ if w_containee is not None: containee = state.py_objects_w2r[w_containee] Py_DECREF(space, w_containee) - containee_ptr = ctypes.addressof(containee._obj._storage) + containee_ptr = rffi.cast(ADDR, containee) try: del state.borrowed_objects[containee_ptr] except KeyError: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Thu Mar 25 22:44:08 2010 @@ -1,4 +1,3 @@ -import ctypes import sys from pypy.rpython.lltypesystem import rffi, lltype @@ -13,7 +12,7 @@ from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ - PyStringObject + PyStringObject, ADDR from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State @@ -298,7 +297,7 @@ @cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1) def PyPyType_Register(space, pto): state = space.fromcache(State) - ptr = ctypes.addressof(pto._obj._storage) + ptr = rffi.cast(ADDR, pto) if ptr not in state.py_objects_r2w: w_obj = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) From fijal at codespeak.net Thu Mar 25 22:59:34 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 22:59:34 +0100 (CET) Subject: [pypy-svn] r72859 - pypy/branch/kill-asm-call/pypy/jit/metainterp Message-ID: <20100325215934.79B95282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 22:59:33 2010 New Revision: 72859 Modified: pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py Log: Insert Nones for void args in case we're on llinterp Modified: pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py Thu Mar 25 22:59:33 2010 @@ -80,7 +80,15 @@ if hasattr(funcobj, 'graph'): llinterp = LLInterpreter(rtyper) #, exc_data_ptr=exc_data_ptr) def on_top_of_llinterp(*args): - return llinterp.eval_graph(funcobj.graph, list(args)) + real_args = [] + i = 0 + for arg in funcobj.graph.startblock.inputargs: + if arg.concretetype is lltype.Void: + real_args.append(None) + else: + real_args.append(args[i]) + i += 1 + return llinterp.eval_graph(funcobj.graph, real_args) else: assert hasattr(funcobj, '_callable') def on_top_of_llinterp(*args): From xoraxax at codespeak.net Thu Mar 25 23:15:23 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 23:15:23 +0100 (CET) Subject: [pypy-svn] r72860 - pypy/branch/cpython-extension/pypy/interpreter/test Message-ID: <20100325221523.85BD1282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 25 23:15:21 2010 New Revision: 72860 Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_argument.py Log: Remove unpack_cpy test. Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_argument.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_argument.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_argument.py Thu Mar 25 23:15:21 2010 @@ -135,12 +135,6 @@ assert args1.keywords is args.keywords assert args1.keywords_w is args.keywords_w - def test_unpack_cpy(self): - space = DummySpace() - args = Arguments(space, ["0"]) - assert space.eq_w(args.unpack_cpy(), space.newtuple([space.newlist([space.wrap("0")]), space.newdict()])) - assert space.eq_w(args.unpack_cpy(1), space.newtuple([space.newlist(), space.newdict()])) - def test_fixedunpacked(self): space = DummySpace() From xoraxax at codespeak.net Thu Mar 25 23:19:05 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Thu, 25 Mar 2010 23:19:05 +0100 (CET) Subject: [pypy-svn] r72861 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100325221905.12C75282BDB@codespeak.net> Author: xoraxax Date: Thu Mar 25 23:19:03 2010 New Revision: 72861 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Log: Problem resolved, I did not svn up. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_object.py Thu Mar 25 23:19:03 2010 @@ -37,7 +37,6 @@ api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(5)) assert not api.PyErr_Occurred() assert x.test == 5 - py.test.skip("Fails in the next line, amaury?") assert api.PyObject_HasAttr(space.wrap(x), space.wrap('test')) api.PyObject_SetAttr(space.wrap(x), space.wrap('test'), space.wrap(10)) assert x.test == 10 From afa at codespeak.net Thu Mar 25 23:46:27 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 25 Mar 2010 23:46:27 +0100 (CET) Subject: [pypy-svn] r72862 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100325224627.8D604282BDB@codespeak.net> Author: afa Date: Thu Mar 25 23:46:25 2010 New Revision: 72862 Added: pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO Log: Update TODO, start a technical documentation Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Thu Mar 25 23:46:25 2010 @@ -1,52 +1,20 @@ - - Implement C API. - Complete the PyTypeObject initialization code. + - Use a WeakKeyDictionary to count how often a PyObject is allocated for a given wrapped object and use this to assess whether optimizations are useful + - lltype.free in PyObject_Del() sometimes raise an exception (but all - tests pass) + tests pass). FIXED? - Reported by Amaury - Alexander cannot reproduce it + - replace @cpython_api(external=False) by another explicit name: all + it does is a lltype function pointer, no C code involved. -PyStringObject support -====================== - -The problem ------------ - -PyString_AsString() should return a (non-movable) pointer -to the underlying buffer, whereas pypy strings are movable. C code -may temporarily store this address and use it, as long as it owns a -reference to the PyObject. There is no "release" function to specify -that the pointer is not needed any more. - -Note that the pointer may be used to fill the initial value of -string. This is valid only when the string was just allocated, and is -not used elsewhere. - -Proposed solution ------------------ - -Our emulation of the PyStringObject contains an additional member: a -pointer to a char buffer; it may be NULL. - -- A string allocated by pypy will be converted into a PyStringObject - with a NULL buffer. When PyString_AsString() is called, memory is - allocated (with flavor='raw') and content is copied. - -- A string allocated with PyString_FromStringAndSize(NULL, size) will - allocate a buffer with the specified size, but the reference won't - be stored in the global map py_objects_r2w; there won't be a - corresponding object in pypy. When from_ref() or Py_INCREF() is - called, the pypy string is created, and added in py_objects_r2w. - The buffer is then supposed to be immutable. - -- _PyString_Resize works only on not-yet-pypy'd strings, and returns a - similar object. + - refactor management of py_objects_r2w and py_objects_w2r, this can + probably be expressed in terms of _PyObject_GC_TRACK macros. -- PyString_Size don't need to force the object. (in this case, another - "size" member is needed) + - Use the standard CPython attribute names: ob_type, ob_refcnt. -- There could be an (expensive!) check in from_ref() that the buffer - still corresponds to the pypy gc-managed string. + - ob_type should be a PyTypeObject. Added: pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt Thu Mar 25 23:46:25 2010 @@ -0,0 +1,51 @@ +Reference Count +=============== + +XXX + +Borrowed References +=================== + +XXX + +PyStringObject support +====================== + +The problem +----------- + +PyString_AsString() returns a (non-movable) pointer to the underlying +buffer, whereas pypy strings are movable. C code may temporarily +store this address and use it, as long as it owns a reference to the +PyObject. There is no "release" function to specify that the pointer +is not needed any more. + +Note that the pointer may be used to fill the initial value of +string. This is valid only when the string was just allocated, and is +not used elsewhere. + +Proposed solution +----------------- + +Our emulation of the PyStringObject contains an additional member: a +pointer to a char buffer; it may be NULL. + +- A string allocated by pypy will be converted into a PyStringObject + with a NULL buffer. When PyString_AsString() is called, memory is + allocated (with flavor='raw') and content is copied. + +- A string allocated with PyString_FromStringAndSize(NULL, size) will + allocate a buffer with the specified size, but the reference won't + be stored in the global map py_objects_r2w; there won't be a + corresponding object in pypy. When from_ref() or Py_INCREF() is + called, the pypy string is created, and added in py_objects_r2w. + The buffer is then supposed to be immutable. + +- _PyString_Resize works only on not-yet-pypy'd strings, and returns a + similar object. + +- PyString_Size don't need to force the object. (in this case, another + "size" member is needed) + +- There could be an (expensive!) check in from_ref() that the buffer + still corresponds to the pypy gc-managed string. From fijal at codespeak.net Thu Mar 25 23:47:17 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Thu, 25 Mar 2010 23:47:17 +0100 (CET) Subject: [pypy-svn] r72863 - pypy/branch/kill-asm-call/pypy/jit/metainterp Message-ID: <20100325224717.401A5282BDB@codespeak.net> Author: fijal Date: Thu Mar 25 23:47:15 2010 New Revision: 72863 Modified: pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py Log: Revert 72859 Modified: pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/metainterp/support.py Thu Mar 25 23:47:15 2010 @@ -80,15 +80,7 @@ if hasattr(funcobj, 'graph'): llinterp = LLInterpreter(rtyper) #, exc_data_ptr=exc_data_ptr) def on_top_of_llinterp(*args): - real_args = [] - i = 0 - for arg in funcobj.graph.startblock.inputargs: - if arg.concretetype is lltype.Void: - real_args.append(None) - else: - real_args.append(args[i]) - i += 1 - return llinterp.eval_graph(funcobj.graph, real_args) + return llinterp.eval_graph(funcobj.graph, list(args)) else: assert hasattr(funcobj, '_callable') def on_top_of_llinterp(*args): From arigo at codespeak.net Thu Mar 25 23:50:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Mar 2010 23:50:26 +0100 (CET) Subject: [pypy-svn] r72864 - pypy/trunk/pypy/translator/goal Message-ID: <20100325225026.D736A282BDB@codespeak.net> Author: arigo Date: Thu Mar 25 23:50:25 2010 New Revision: 72864 Modified: pypy/trunk/pypy/translator/goal/translate.py Log: Ignore most exceptions when trying to kill _cache. Modified: pypy/trunk/pypy/translator/goal/translate.py ============================================================================== --- pypy/trunk/pypy/translator/goal/translate.py (original) +++ pypy/trunk/pypy/translator/goal/translate.py Thu Mar 25 23:50:25 2010 @@ -11,7 +11,7 @@ # clean up early pypy/_cache try: py.path.local(autopath.pypydir).join('_cache').remove() -except py.error: +except Exception: pass from pypy.config.config import to_optparse, OptionDescription, BoolOption, \ From fijal at codespeak.net Fri Mar 26 01:04:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 01:04:31 +0100 (CET) Subject: [pypy-svn] r72865 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100326000431.4EB5D282BDB@codespeak.net> Author: fijal Date: Fri Mar 26 01:04:30 2010 New Revision: 72865 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Log: Hack a bit more. I think we're getting there Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Fri Mar 26 01:04:30 2010 @@ -1,9 +1,9 @@ import py from pypy.rpython.lltypesystem import lltype, rffi, llmemory -from pypy.jit.backend.llsupport import symbolic +from pypy.jit.backend.llsupport import symbolic, support from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat -from pypy.jit.metainterp import history, support +from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances @@ -218,16 +218,26 @@ def get_call_stub(self): return self.call_stub - def create_call_stub(self, rtyper, FUNC): + def create_call_stub(self, rtyper, RESULT): def process(no, c): if c == 'i': - return 'lltype.cast_primitive(FUNC.ARGS[%d], args[%d].getint())' % (no - 1, no) + return 'args[%d].getint()' % (no,) elif c == 'f': return 'args[%d].getfloat()' % (no,) elif c == 'r': - return 'args[%d].getref(FUNC.ARGS[%d])' % (no, no - 1) + return 'args[%d].getref_base()' % (no,) else: raise Exception("Unknown type %s for type %s" % (c, TP)) + + def TYPE(arg): + if arg == 'i': + return lltype.Signed + elif arg == 'f': + return lltype.Float + elif arg == 'r': + return llmemory.GCREF + elif arg == 'v': + return lltype.Void args = ", ".join([process(i + 1, c) for i, c in enumerate(self.arg_classes)]) @@ -242,10 +252,12 @@ result = 'history.BoxInt(lltype.cast_primitive(lltype.Signed, res))' source = py.code.Source(""" def call_stub(args): - ll_callable = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) - res = support.maybe_on_top_of_llinterp(rtyper, ll_callable)(%(args)s) + fnptr = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) + res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) return %(result)s """ % locals()) + ARGS = [TYPE(arg) for arg in self.arg_classes] + FUNC = lltype.FuncType(ARGS, RESULT) d = locals().copy() d.update(globals()) exec source.compile() in d @@ -257,14 +269,18 @@ class NonGcPtrCallDescr(BaseCallDescr): _clsname = 'NonGcPtrCallDescr' + _tp = 'i' # XXX + def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrCallDescr(NonGcPtrCallDescr): + _tp = 'r' _clsname = 'GcPtrCallDescr' _returns_a_pointer = True class VoidCallDescr(NonGcPtrCallDescr): + _tp = 'v' _clsname = 'VoidCallDescr' _returns_a_void = True @@ -295,7 +311,7 @@ return cache[key] except KeyError: calldescr = cls(arg_classes, extrainfo) - calldescr.create_call_stub(gccache.rtyper, lltype.FuncType(ARGS, RESULT)) + calldescr.create_call_stub(gccache.rtyper, RESULT) cache[key] = calldescr return calldescr Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Fri Mar 26 01:04:30 2010 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.annlowlevel import llhelper from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.jit.metainterp.history import BoxInt, BoxPtr, set_future_values,\ @@ -478,12 +478,16 @@ try: return callstub(args) except Exception, e: - if we_are_translated(): - xxx + if not we_are_translated(): + if not type(e) is LLException: + raise + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + e.args[1]) + self.saved_exception = rffi.cast(lltype.Signed, e.args[0]) else: - import pdb - pdb.set_trace() - + xxx + return None + def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) From fijal at codespeak.net Fri Mar 26 01:52:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 01:52:55 +0100 (CET) Subject: [pypy-svn] r72866 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100326005255.D5C97282BDB@codespeak.net> Author: fijal Date: Fri Mar 26 01:52:52 2010 New Revision: 72866 Added: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/support.py (contents, props changed) Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Log: A fix and a missing file Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Fri Mar 26 01:52:52 2010 @@ -14,6 +14,8 @@ from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr +empty_int_box = BoxInt(0) + class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts @@ -486,7 +488,11 @@ self.saved_exception = rffi.cast(lltype.Signed, e.args[0]) else: xxx - return None + if calldescr.returns_a_void(): + return None + # we need a box to put in env. This is harmless since nobody + # should depend on it's value or type + return empty_int_box def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) Added: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/support.py ============================================================================== --- (empty file) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/support.py Fri Mar 26 01:52:52 2010 @@ -0,0 +1,50 @@ +from pypy.translator.simplify import get_funcobj +from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.lltypesystem import lltype, rffi +from pypy.rpython.extregistry import ExtRegistryEntry + +def maybe_on_top_of_llinterp(rtyper, fnptr): + # Run a generated graph on top of the llinterp for testing. + # When translated, this just returns the fnptr. + def process_args(args): + real_args = [] + ARGS = lltype.typeOf(funcobj).ARGS + i = 0 + for ARG in ARGS: + if ARG is lltype.Void: + real_args.append(None) + else: + if ARG is lltype.Float: + real_args.append(args[i]) + elif isinstance(ARG, lltype.Primitive): + real_args.append(lltype.cast_primitive(ARG, args[i])) + elif isinstance(ARG, lltype.Ptr): + if ARG.TO._gckind == 'gc': + real_args.append(lltype.cast_opaque_ptr(ARG, args[i])) + else: + real_args.append(rffi.cast(ARG, args[i])) + else: + raise Exception("Unexpected arg: %s" % ARG) + i += 1 + return real_args + + funcobj = get_funcobj(fnptr) + if hasattr(funcobj, 'graph'): + llinterp = LLInterpreter(rtyper) #, exc_data_ptr=exc_data_ptr) + def on_top_of_llinterp(*args): + real_args = process_args(args) + return llinterp.eval_graph(funcobj.graph, real_args) + else: + assert hasattr(funcobj, '_callable') + def on_top_of_llinterp(*args): + args = process_args(args) + return funcobj._callable(*args) + return on_top_of_llinterp + +class Entry(ExtRegistryEntry): + _about_ = maybe_on_top_of_llinterp + def compute_result_annotation(self, s_rtyper, s_fnptr): + return s_fnptr + def specialize_call(self, hop): + hop.exception_cannot_occur() + return hop.inputarg(hop.args_r[1], arg=1) From fijal at codespeak.net Fri Mar 26 02:06:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 02:06:00 +0100 (CET) Subject: [pypy-svn] r72867 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100326010600.82657282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 02:05:54 2010 New Revision: 72867 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Log: Fix the translated version Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Fri Mar 26 02:05:54 2010 @@ -13,6 +13,7 @@ from pypy.jit.backend.llsupport.descr import get_field_descr, BaseFieldDescr from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr +from pypy.rpython.annlowlevel import cast_instance_to_base_ptr empty_int_box = BoxInt(0) @@ -487,7 +488,10 @@ e.args[1]) self.saved_exception = rffi.cast(lltype.Signed, e.args[0]) else: - xxx + ptr = cast_instance_to_base_ptr(e) + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + ptr) + self.saved_exception = rffi.cast(lltype.Signed, ptr.typeptr) if calldescr.returns_a_void(): return None # we need a box to put in env. This is harmless since nobody From fijal at codespeak.net Fri Mar 26 02:12:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 02:12:03 +0100 (CET) Subject: [pypy-svn] r72868 - pypy/build/doc Message-ID: <20100326011203.85640282BDB@codespeak.net> Author: fijal Date: Fri Mar 26 02:12:02 2010 New Revision: 72868 Modified: pypy/build/doc/ssh_config Log: Add tannit Modified: pypy/build/doc/ssh_config ============================================================================== --- pypy/build/doc/ssh_config (original) +++ pypy/build/doc/ssh_config Fri Mar 26 02:12:02 2010 @@ -39,3 +39,5 @@ Hostname codespeak.net Port 2222 +Host tannit + Hostname 83.140.78.199 From fijal at codespeak.net Fri Mar 26 02:16:43 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 02:16:43 +0100 (CET) Subject: [pypy-svn] r72869 - pypy/branch/kill-asm-call/pypy/jit/backend/llsupport Message-ID: <20100326011643.D67B2282BDB@codespeak.net> Author: fijal Date: Fri Mar 26 02:16:42 2010 New Revision: 72869 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Log: Use rffi.cast here, it can be a non-gc object as well Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Fri Mar 26 02:16:42 2010 @@ -249,7 +249,7 @@ elif self.returns_a_void(): result = 'None' else: - result = 'history.BoxInt(lltype.cast_primitive(lltype.Signed, res))' + result = 'history.BoxInt(rffi.cast(lltype.Signed, res))' source = py.code.Source(""" def call_stub(args): fnptr = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) From benjamin at codespeak.net Fri Mar 26 02:23:05 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 02:23:05 +0100 (CET) Subject: [pypy-svn] r72870 - pypy/trunk/pypy/module/imp Message-ID: <20100326012305.83B51282BDB@codespeak.net> Author: benjamin Date: Fri Mar 26 02:23:04 2010 New Revision: 72870 Modified: pypy/trunk/pypy/module/imp/importing.py Log: squash annotation warning Modified: pypy/trunk/pypy/module/imp/importing.py ============================================================================== --- pypy/trunk/pypy/module/imp/importing.py (original) +++ pypy/trunk/pypy/module/imp/importing.py Fri Mar 26 02:23:04 2010 @@ -324,6 +324,7 @@ modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED): + assert suffix is not None filename = filepart + suffix stream = streamio.open_file_as_stream(filename, filemode) try: From benjamin at codespeak.net Fri Mar 26 02:46:55 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 02:46:55 +0100 (CET) Subject: [pypy-svn] r72871 - pypy/trunk/pypy/interpreter Message-ID: <20100326014655.B9BEA282BDB@codespeak.net> Author: benjamin Date: Fri Mar 26 02:46:54 2010 New Revision: 72871 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: move opcode implementations out of dispatch_bytecode Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 02:46:54 2010 @@ -206,37 +206,6 @@ next_instr += 3 oparg = (oparg << 16) | (hi << 8) | lo - if opcode == opcodedesc.RETURN_VALUE.index: - w_returnvalue = self.popvalue() - block = self.unrollstack(SReturnValue.kind) - if block is None: - self.pushvalue(w_returnvalue) # XXX ping pong - raise Return - else: - unroller = SReturnValue(w_returnvalue) - next_instr = block.handle(self, unroller) - return next_instr # now inside a 'finally' block - - if opcode == opcodedesc.YIELD_VALUE.index: - #self.last_instr = intmask(next_instr - 1) XXX clean up! - raise Yield - - if opcode == opcodedesc.END_FINALLY.index: - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr - - if opcode == opcodedesc.JUMP_ABSOLUTE.index: - return self.JUMP_ABSOLUTE(oparg, next_instr, ec) - if we_are_translated(): from pypy.rlib import rstack # for resume points @@ -245,7 +214,7 @@ if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): - continue # e.g. for JUMP_FORWARD, implemented above + continue # e.g. for JUMP_ABSOLUTE, implemented above if opcode == opdesc.index: # dispatch to the opcode method @@ -814,6 +783,9 @@ f.space.str_w(w_name)) f.pushvalue(w_obj) + def JUMP_ABSOLUTE(f, jumpto, next_instr): + return jumpto + def JUMP_FORWARD(f, jumpby, next_instr, *ignored): next_instr += jumpby return next_instr @@ -830,9 +802,6 @@ next_instr += stepby return next_instr - def JUMP_ABSOLUTE(f, jumpto, next_instr, *ignored): - return jumpto - def GET_ITER(f, *ignored): w_iterable = f.popvalue() w_iterator = f.space.iter(w_iterable) @@ -867,6 +836,19 @@ block = FinallyBlock(f, next_instr + offsettoend) f.append_block(block) + def END_FINALLY(self, oparg, next_instr): + unroller = self.end_finally() + if isinstance(unroller, SuspendedUnroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + next_instr = block.handle(self, unroller) + return next_instr + def WITH_CLEANUP(f, *ignored): # see comment in END_FINALLY for stack state w_exitfunc = f.popvalue() @@ -886,12 +868,26 @@ f.space.w_None, f.space.w_None, f.space.w_None) - + + def YIELD_VALUE(f, oparg, next_instr): + raise Yield + + def RETURN_VALUE(self, oparg, next_instr): + w_returnvalue = self.popvalue() + block = self.unrollstack(SReturnValue.kind) + if block is None: + self.pushvalue(w_returnvalue) + raise Return + unroller = SReturnValue(w_returnvalue) + next_instr = block.handle(self, unroller) + return next_instr # now inside a 'finally' block + + @jit.unroll_safe 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 if n_keywords: From fijal at codespeak.net Fri Mar 26 03:48:07 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 03:48:07 +0100 (CET) Subject: [pypy-svn] r72873 - in pypy/branch/kill-asm-call/pypy/jit/backend/llsupport: . test Message-ID: <20100326024807.2AD9D282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 03:48:06 2010 New Revision: 72873 Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Log: Return a correct empty box. I think this is the cause of crashes (not sure) Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/descr.py Fri Mar 26 03:48:06 2010 @@ -179,6 +179,7 @@ # CallDescrs class BaseCallDescr(AbstractDescr): + empty_box = BoxInt(0) _clsname = '' loop_token = None arg_classes = '' # <-- annotation hack @@ -190,15 +191,6 @@ def get_extra_info(self): return self.extrainfo - def instantiate_arg_classes(self): - result = [] - for c in self.arg_classes: - if c == 'i': box = BoxInt() - elif c == 'f': box = BoxFloat() - else: box = BoxPtr() - result.append(box) - return result - _returns_a_pointer = False # unless overridden by GcPtrCallDescr _returns_a_float = False # unless overridden by FloatCallDescr _returns_a_void = False # unless overridden by VoidCallDescr @@ -269,18 +261,17 @@ class NonGcPtrCallDescr(BaseCallDescr): _clsname = 'NonGcPtrCallDescr' - _tp = 'i' # XXX def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrCallDescr(NonGcPtrCallDescr): - _tp = 'r' + empty_box = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) _clsname = 'GcPtrCallDescr' _returns_a_pointer = True class VoidCallDescr(NonGcPtrCallDescr): - _tp = 'v' + empty_box = None _clsname = 'VoidCallDescr' _returns_a_void = True @@ -339,6 +330,7 @@ # if TYPE is lltype.Float: setattr(Descr, floatattrname, True) + Descr.empty_box = BoxFloat(0.0) # _cache[nameprefix, TYPE] = Descr return Descr Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/llmodel.py Fri Mar 26 03:48:06 2010 @@ -492,11 +492,7 @@ self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, ptr) self.saved_exception = rffi.cast(lltype.Signed, ptr.typeptr) - if calldescr.returns_a_void(): - return None - # we need a box to put in env. This is harmless since nobody - # should depend on it's value or type - return empty_int_box + return calldescr.empty_box def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) Modified: pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/test/test_descr.py Fri Mar 26 03:48:06 2010 @@ -3,7 +3,7 @@ from pypy.jit.backend.llsupport import symbolic from pypy.rlib.objectmodel import Symbolic from pypy.rpython.annlowlevel import llhelper -from pypy.jit.metainterp.history import BoxInt +from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr def test_get_size_descr(): c0 = GcCache(False) @@ -148,6 +148,7 @@ assert not descr1.returns_a_pointer() assert not descr1.returns_a_float() assert descr1.arg_classes == "ii" + assert isinstance(descr1.empty_box, BoxInt) # T = lltype.GcStruct('T') descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) @@ -155,15 +156,22 @@ assert descr2.returns_a_pointer() assert not descr2.returns_a_float() assert descr2.arg_classes == "r" + assert isinstance(descr2.empty_box, BoxPtr) # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) # + V = lltype.Struct('V', ('x', lltype.Signed)) + assert isinstance(get_call_descr(c0, [], lltype.Ptr(V)).empty_box, BoxInt) + # + assert get_call_descr(c0, [], lltype.Void).empty_box is None + # descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float) assert descr4.get_result_size(False) == rffi.sizeof(lltype.Float) assert not descr4.returns_a_pointer() assert descr4.returns_a_float() assert descr4.arg_classes == "ff" + assert isinstance(descr4.empty_box, BoxFloat) def test_get_call_descr_translated(): c1 = GcCache(True) From benjamin at codespeak.net Fri Mar 26 04:15:39 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 04:15:39 +0100 (CET) Subject: [pypy-svn] r72874 - pypy/trunk/pypy/interpreter Message-ID: <20100326031539.8A6A6282BE4@codespeak.net> Author: benjamin Date: Fri Mar 26 04:15:37 2010 New Revision: 72874 Modified: pypy/trunk/pypy/interpreter/nestedscope.py pypy/trunk/pypy/interpreter/pyopcode.py Log: cleanup opcode implementations * 'f' -> self * normalize argument lists * remove old commented out code Modified: pypy/trunk/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/trunk/pypy/interpreter/nestedscope.py (original) +++ pypy/trunk/pypy/interpreter/nestedscope.py Fri Mar 26 04:15:37 2010 @@ -169,51 +169,51 @@ ### extra opcodes ### - def LOAD_CLOSURE(f, varindex, *ignored): + def LOAD_CLOSURE(self, varindex, next_instr): # nested scopes: access the cell object - cell = f.cells[varindex] - w_value = f.space.wrap(cell) - f.pushvalue(w_value) + cell = self.cells[varindex] + w_value = self.space.wrap(cell) + self.pushvalue(w_value) - def LOAD_DEREF(f, varindex, *ignored): + def LOAD_DEREF(self, varindex, next_instr): # nested scopes: access a variable through its cell object - cell = f.cells[varindex] + cell = self.cells[varindex] try: w_value = cell.get() except ValueError: - varname = f.getfreevarname(varindex) - if f.iscellvar(varindex): + varname = self.getfreevarname(varindex) + if self.iscellvar(varindex): message = "local variable '%s' referenced before assignment"%varname - w_exc_type = f.space.w_UnboundLocalError + w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" " in enclosing scope"%varname) - w_exc_type = f.space.w_NameError - raise OperationError(w_exc_type, f.space.wrap(message)) + w_exc_type = self.space.w_NameError + raise OperationError(w_exc_type, self.space.wrap(message)) else: - f.pushvalue(w_value) + self.pushvalue(w_value) - def STORE_DEREF(f, varindex, *ignored): + def STORE_DEREF(self, varindex, next_instr): # nested scopes: access a variable through its cell object - w_newvalue = f.popvalue() - cell = f.cells[varindex] + w_newvalue = self.popvalue() + cell = self.cells[varindex] cell.set(w_newvalue) @jit.unroll_safe - def MAKE_CLOSURE(f, numdefaults, *ignored): - w_codeobj = f.popvalue() - codeobj = f.space.interp_w(pycode.PyCode, w_codeobj) + def MAKE_CLOSURE(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + codeobj = self.space.interp_w(pycode.PyCode, w_codeobj) if codeobj.magic >= 0xa0df281: # CPython 2.5 AST branch merge - w_freevarstuple = f.popvalue() - freevars = [f.space.interp_w(Cell, cell) - for cell in f.space.fixedview(w_freevarstuple)] + w_freevarstuple = self.popvalue() + freevars = [self.space.interp_w(Cell, cell) + for cell in self.space.fixedview(w_freevarstuple)] else: nfreevars = len(codeobj.co_freevars) - freevars = [f.space.interp_w(Cell, f.popvalue()) + freevars = [self.space.interp_w(Cell, self.popvalue()) for i in range(nfreevars)] freevars.reverse() - defaultarguments = [f.popvalue() for i in range(numdefaults)] + defaultarguments = [self.popvalue() for i in range(numdefaults)] defaultarguments.reverse() - fn = function.Function(f.space, codeobj, f.w_globals, + fn = function.Function(self.space, codeobj, self.w_globals, defaultarguments, freevars) - f.pushvalue(f.space.wrap(fn)) + self.pushvalue(self.space.wrap(fn)) Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 04:15:37 2010 @@ -21,23 +21,23 @@ def unaryoperation(operationname): """NOT_RPYTHON""" - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_1 = f.popvalue() + def opimpl(self, *ignored): + operation = getattr(self.space, operationname) + w_1 = self.popvalue() w_result = operation(w_1) - f.pushvalue(w_result) + self.pushvalue(w_result) opimpl.unaryop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) def binaryoperation(operationname): - """NOT_RPYTHON""" - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_2 = f.popvalue() - w_1 = f.popvalue() + """NOT_RPYTHON""" + def opimpl(self, *ignored): + operation = getattr(self.space, operationname) + w_2 = self.popvalue() + w_1 = self.popvalue() w_result = operation(w_1, w_2) - f.pushvalue(w_result) + self.pushvalue(w_result) opimpl.binop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) @@ -63,10 +63,10 @@ class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - + # for logbytecode: last_opcode = -1 - + ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -276,78 +276,66 @@ ## See also nestedscope.py for the rest. ## - # the 'self' argument of opcode implementations is called 'f' - # for historical reasons - - def NOP(f, *ignored): + def NOP(self, oparg, next_instr): pass - def LOAD_FAST(f, varindex, *ignored): + def LOAD_FAST(self, varindex, next_instr): # access a local variable directly - w_value = f.fastlocals_w[varindex] + w_value = self.fastlocals_w[varindex] if w_value is None: - f._load_fast_failed(varindex) - f.pushvalue(w_value) + self._load_fast_failed(varindex) + self.pushvalue(w_value) LOAD_FAST._always_inline_ = True - def _load_fast_failed(f, varindex): - varname = f.getlocalvarname(varindex) + def _load_fast_failed(self, varindex): + varname = self.getlocalvarname(varindex) message = "local variable '%s' referenced before assignment" - raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) + raise operationerrfmt(self.space.w_UnboundLocalError, message, varname) _load_fast_failed._dont_inline_ = True - def LOAD_CONST(f, constindex, *ignored): - w_const = f.getconstant_w(constindex) - f.pushvalue(w_const) + def LOAD_CONST(self, constindex, next_instr): + w_const = self.getconstant_w(constindex) + self.pushvalue(w_const) - def STORE_FAST(f, varindex, *ignored): - w_newvalue = f.popvalue() + def STORE_FAST(self, varindex, next_instr): + w_newvalue = self.popvalue() assert w_newvalue is not None - f.fastlocals_w[varindex] = w_newvalue - #except: - # print "exception: got index error" - # print " varindex:", varindex - # print " len(locals_w)", len(f.locals_w) - # import dis - # print dis.dis(f.pycode) - # print "co_varnames", f.pycode.co_varnames - # print "co_nlocals", f.pycode.co_nlocals - # raise - - def POP_TOP(f, *ignored): - f.popvalue() - - def ROT_TWO(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_2) - - def ROT_THREE(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - w_3 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_3) - f.pushvalue(w_2) - - def ROT_FOUR(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - w_3 = f.popvalue() - w_4 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_4) - f.pushvalue(w_3) - f.pushvalue(w_2) - - def DUP_TOP(f, *ignored): - w_1 = f.peekvalue() - f.pushvalue(w_1) + self.fastlocals_w[varindex] = w_newvalue + + def POP_TOP(self, oparg, next_instr): + self.popvalue() - def DUP_TOPX(f, itemcount, *ignored): + def ROT_TWO(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_2) + + def ROT_THREE(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def ROT_FOUR(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + w_4 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_4) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def DUP_TOP(self, oparg, next_instr): + w_1 = self.peekvalue() + self.pushvalue(w_1) + + def DUP_TOPX(self, itemcount, next_instr): assert 1 <= itemcount <= 5, "limitation of the current interpreter" - f.dupvalues(itemcount) + self.dupvalues(itemcount) UNARY_POSITIVE = unaryoperation("pos") UNARY_NEGATIVE = unaryoperation("neg") @@ -355,11 +343,11 @@ UNARY_CONVERT = unaryoperation("repr") UNARY_INVERT = unaryoperation("invert") - def BINARY_POWER(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = f.space.pow(w_1, w_2, f.space.w_None) - f.pushvalue(w_result) + def BINARY_POWER(self, oparg, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = self.space.pow(w_1, w_2, self.space.w_None) + self.pushvalue(w_result) BINARY_MULTIPLY = binaryoperation("mul") BINARY_TRUE_DIVIDE = binaryoperation("truediv") @@ -376,11 +364,11 @@ BINARY_XOR = binaryoperation("xor") BINARY_OR = binaryoperation("or_") - def INPLACE_POWER(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = f.space.inplace_pow(w_1, w_2) - f.pushvalue(w_result) + def INPLACE_POWER(self, oparg, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = self.space.inplace_pow(w_1, w_2) + self.pushvalue(w_result) INPLACE_MULTIPLY = binaryoperation("inplace_mul") INPLACE_TRUE_DIVIDE = binaryoperation("inplace_truediv") @@ -396,129 +384,130 @@ INPLACE_XOR = binaryoperation("inplace_xor") INPLACE_OR = binaryoperation("inplace_or") - def slice(f, w_start, w_end): - w_obj = f.popvalue() - w_result = f.space.getslice(w_obj, w_start, w_end) - f.pushvalue(w_result) - - def SLICE_0(f, *ignored): - f.slice(f.space.w_None, f.space.w_None) - - def SLICE_1(f, *ignored): - w_start = f.popvalue() - f.slice(w_start, f.space.w_None) - - def SLICE_2(f, *ignored): - w_end = f.popvalue() - f.slice(f.space.w_None, w_end) - - def SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.slice(w_start, w_end) - - def storeslice(f, w_start, w_end): - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setslice(w_obj, w_start, w_end, w_newvalue) - - def STORE_SLICE_0(f, *ignored): - f.storeslice(f.space.w_None, f.space.w_None) - - def STORE_SLICE_1(f, *ignored): - w_start = f.popvalue() - f.storeslice(w_start, f.space.w_None) - - def STORE_SLICE_2(f, *ignored): - w_end = f.popvalue() - f.storeslice(f.space.w_None, w_end) - - def STORE_SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.storeslice(w_start, w_end) - - def deleteslice(f, w_start, w_end): - w_obj = f.popvalue() - f.space.delslice(w_obj, w_start, w_end) - - def DELETE_SLICE_0(f, *ignored): - f.deleteslice(f.space.w_None, f.space.w_None) - - def DELETE_SLICE_1(f, *ignored): - w_start = f.popvalue() - f.deleteslice(w_start, f.space.w_None) - - def DELETE_SLICE_2(f, *ignored): - w_end = f.popvalue() - f.deleteslice(f.space.w_None, w_end) - - def DELETE_SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.deleteslice(w_start, w_end) + def slice(self, w_start, w_end): + w_obj = self.popvalue() + w_result = self.space.getslice(w_obj, w_start, w_end) + self.pushvalue(w_result) + + def SLICE_0(self, oparg, next_instr): + self.slice(self.space.w_None, self.space.w_None) + + def SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.slice(w_start, self.space.w_None) + + def SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.slice(self.space.w_None, w_end) + + def SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.slice(w_start, w_end) + + def storeslice(self, w_start, w_end): + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setslice(w_obj, w_start, w_end, w_newvalue) + + def STORE_SLICE_0(self, oparg, next_instr): + self.storeslice(self.space.w_None, self.space.w_None) + + def STORE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.storeslice(w_start, self.space.w_None) + + def STORE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.storeslice(self.space.w_None, w_end) + + def STORE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.storeslice(w_start, w_end) + + def deleteslice(self, w_start, w_end): + w_obj = self.popvalue() + self.space.delslice(w_obj, w_start, w_end) + + def DELETE_SLICE_0(self, oparg, next_instr): + self.deleteslice(self.space.w_None, self.space.w_None) + + def DELETE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.deleteslice(w_start, self.space.w_None) + + def DELETE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.deleteslice(self.space.w_None, w_end) + + def DELETE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.deleteslice(w_start, w_end) - def STORE_SUBSCR(f, *ignored): + def STORE_SUBSCR(self, oparg, next_instr): "obj[subscr] = newvalue" - w_subscr = f.popvalue() - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setitem(w_obj, w_subscr, w_newvalue) + w_subscr = self.popvalue() + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setitem(w_obj, w_subscr, w_newvalue) - def DELETE_SUBSCR(f, *ignored): + def DELETE_SUBSCR(self, oparg, next_instr): "del obj[subscr]" - w_subscr = f.popvalue() - w_obj = f.popvalue() - f.space.delitem(w_obj, w_subscr) - - def PRINT_EXPR(f, *ignored): - w_expr = f.popvalue() - print_expr(f.space, w_expr) - - def PRINT_ITEM_TO(f, *ignored): - w_stream = f.popvalue() - w_item = f.popvalue() - if f.space.is_w(w_stream, f.space.w_None): - w_stream = sys_stdout(f.space) # grumble grumble special cases - print_item_to(f.space, w_item, w_stream) - - def PRINT_ITEM(f, *ignored): - w_item = f.popvalue() - print_item(f.space, w_item) - - def PRINT_NEWLINE_TO(f, *ignored): - w_stream = f.popvalue() - if f.space.is_w(w_stream, f.space.w_None): - w_stream = sys_stdout(f.space) # grumble grumble special cases - print_newline_to(f.space, w_stream) + w_subscr = self.popvalue() + w_obj = self.popvalue() + self.space.delitem(w_obj, w_subscr) + + def PRINT_EXPR(self, oparg, next_instr): + w_expr = self.popvalue() + print_expr(self.space, w_expr) + + def PRINT_ITEM_TO(self, oparg, next_instr): + w_stream = self.popvalue() + w_item = self.popvalue() + if self.space.is_w(w_stream, self.space.w_None): + w_stream = sys_stdout(self.space) # grumble grumble special cases + print_item_to(self.space, w_item, w_stream) + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + print_item(self.space, w_item) + + def PRINT_NEWLINE_TO(self, oparg, next_instr): + w_stream = self.popvalue() + if self.space.is_w(w_stream, self.space.w_None): + w_stream = sys_stdout(self.space) # grumble grumble special cases + print_newline_to(self.space, w_stream) - def PRINT_NEWLINE(f, *ignored): - print_newline(f.space) + def PRINT_NEWLINE(self, oparg, next_instr): + print_newline(self.space) - def BREAK_LOOP(f, *ignored): - next_instr = f.unrollstack_and_jump(SBreakLoop.singleton) - return next_instr + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) - def CONTINUE_LOOP(f, startofloop, *ignored): + def CONTINUE_LOOP(self, startofloop, next_instr): unroller = SContinueLoop(startofloop) - next_instr = f.unrollstack_and_jump(unroller) - return next_instr + return self.unrollstack_and_jump(unroller) - def RAISE_VARARGS(f, nbargs, *ignored): - space = f.space + def RAISE_VARARGS(self, nbargs, next_instr): + space = self.space if nbargs == 0: operror = space.getexecutioncontext().sys_exc_info() if operror is None: raise OperationError(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) # re-raise, no new traceback obj will be attached - f.last_exception = operror + self.last_exception = operror raise Reraise w_value = w_traceback = space.w_None - if nbargs >= 3: w_traceback = f.popvalue() - if nbargs >= 2: w_value = f.popvalue() - if 1: w_type = f.popvalue() + if nbargs >= 3: + w_traceback = self.popvalue() + if nbargs >= 2: + w_value = self.popvalue() + if 1: + w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) if not space.full_exceptions or space.is_w(w_traceback, space.w_None): @@ -532,151 +521,154 @@ # special 3-arguments raise, no new traceback obj will be attached raise RaiseWithExplicitTraceback(operror) - def LOAD_LOCALS(f, *ignored): - f.pushvalue(f.w_locals) + def LOAD_LOCALS(self, oparg, next_instr): + self.pushvalue(self.w_locals) - def EXEC_STMT(f, *ignored): - w_locals = f.popvalue() - w_globals = f.popvalue() - w_prog = f.popvalue() - flags = f.space.getexecutioncontext().compiler.getcodeflags(f.pycode) - w_compile_flags = f.space.wrap(flags) - w_resulttuple = prepare_exec(f.space, f.space.wrap(f), w_prog, + def EXEC_STMT(self, oparg, next_instr): + w_locals = self.popvalue() + w_globals = self.popvalue() + w_prog = self.popvalue() + ec = self.space.getexecutioncontext() + flags = ec.compiler.getcodeflags(self.pycode) + w_compile_flags = self.space.wrap(flags) + w_resulttuple = prepare_exec(self.space, self.space.wrap(self), w_prog, w_globals, w_locals, w_compile_flags, - f.space.wrap(f.get_builtin()), - f.space.gettypeobject(PyCode.typedef)) - w_prog, w_globals, w_locals = f.space.fixedview(w_resulttuple, 3) + self.space.wrap(self.get_builtin()), + self.space.gettypeobject(PyCode.typedef)) + w_prog, w_globals, w_locals = self.space.fixedview(w_resulttuple, 3) - plain = f.w_locals is not None and f.space.is_w(w_locals, f.w_locals) + plain = (self.w_locals is not None and + self.space.is_w(w_locals, self.w_locals)) if plain: - w_locals = f.getdictscope() - co = f.space.interp_w(eval.Code, w_prog) - co.exec_code(f.space, w_globals, w_locals) + w_locals = self.getdictscope() + co = self.space.interp_w(eval.Code, w_prog) + co.exec_code(self.space, w_globals, w_locals) if plain: - f.setdictscope(w_locals) + self.setdictscope(w_locals) - def POP_BLOCK(f, *ignored): - block = f.pop_block() - block.cleanup(f) # the block knows how to clean up the value stack + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanup(self) # the block knows how to clean up the value stack - def end_finally(f): + def end_finally(self): # unlike CPython, when we reach this opcode the value stack has # always been set up as follows (topmost first): # [exception type or None] # [exception value or None] # [wrapped stack unroller ] - f.popvalue() # ignore the exception type - f.popvalue() # ignore the exception value - w_unroller = f.popvalue() - unroller = f.space.interpclass_w(w_unroller) + self.popvalue() # ignore the exception type + self.popvalue() # ignore the exception value + w_unroller = self.popvalue() + unroller = self.space.interpclass_w(w_unroller) return unroller - def BUILD_CLASS(f, *ignored): - w_methodsdict = f.popvalue() - w_bases = f.popvalue() - w_name = f.popvalue() - w_metaclass = find_metaclass(f.space, w_bases, - w_methodsdict, f.w_globals, - f.space.wrap(f.get_builtin())) - w_newclass = f.space.call_function(w_metaclass, w_name, - w_bases, w_methodsdict) - f.pushvalue(w_newclass) - - def STORE_NAME(f, varindex, *ignored): - varname = f.getname_u(varindex) - w_newvalue = f.popvalue() - f.space.set_str_keyed_item(f.w_locals, varname, w_newvalue) + def BUILD_CLASS(self, oparg, next_instr): + w_methodsdict = self.popvalue() + w_bases = self.popvalue() + w_name = self.popvalue() + w_metaclass = find_metaclass(self.space, w_bases, + w_methodsdict, self.w_globals, + self.space.wrap(self.get_builtin())) + w_newclass = self.space.call_function(w_metaclass, w_name, + w_bases, w_methodsdict) + self.pushvalue(w_newclass) + + def STORE_NAME(self, varindex, next_instr): + varname = self.getname_u(varindex) + w_newvalue = self.popvalue() + self.space.set_str_keyed_item(self.w_locals, varname, w_newvalue) - def DELETE_NAME(f, varindex, *ignored): - w_varname = f.getname_w(varindex) + def DELETE_NAME(self, varindex, next_instr): + w_varname = self.getname_w(varindex) try: - f.space.delitem(f.w_locals, w_varname) + self.space.delitem(self.w_locals, w_varname) except OperationError, e: # catch KeyErrors and turn them into NameErrors - if not e.match(f.space, f.space.w_KeyError): + if not e.match(self.space, self.space.w_KeyError): raise message = "name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, message, - f.space.str_w(w_varname)) + raise operationerrfmt(self.space.w_NameError, message, + self.space.str_w(w_varname)) - def UNPACK_SEQUENCE(f, itemcount, *ignored): - w_iterable = f.popvalue() + def UNPACK_SEQUENCE(self, itemcount, next_instr): + w_iterable = self.popvalue() try: - items = f.space.fixedview(w_iterable, itemcount) + items = self.space.fixedview(w_iterable, itemcount) except UnpackValueError, e: - raise OperationError(f.space.w_ValueError, f.space.wrap(e.msg)) - f.pushrevvalues(itemcount, items) + w_msg = self.space.wrap(e.msg) + raise OperationError(self.space.w_ValueError, w_msg) + self.pushrevvalues(itemcount, items) - def STORE_ATTR(f, nameindex, *ignored): + def STORE_ATTR(self, nameindex, next_instr): "obj.attributename = newvalue" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setattr(w_obj, w_attributename, w_newvalue) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setattr(w_obj, w_attributename, w_newvalue) - def DELETE_ATTR(f, nameindex, *ignored): + def DELETE_ATTR(self, nameindex, next_instr): "del obj.attributename" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - f.space.delattr(w_obj, w_attributename) - - def STORE_GLOBAL(f, nameindex, *ignored): - varname = f.getname_u(nameindex) - w_newvalue = f.popvalue() - f.space.set_str_keyed_item(f.w_globals, varname, w_newvalue) - - def DELETE_GLOBAL(f, nameindex, *ignored): - w_varname = f.getname_w(nameindex) - f.space.delitem(f.w_globals, w_varname) - - def LOAD_NAME(f, nameindex, *ignored): - if f.w_locals is not f.w_globals: - w_varname = f.getname_w(nameindex) - w_value = f.space.finditem(f.w_locals, w_varname) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + self.space.delattr(w_obj, w_attributename) + + def STORE_GLOBAL(self, nameindex, next_instr): + varname = self.getname_u(nameindex) + w_newvalue = self.popvalue() + self.space.set_str_keyed_item(self.w_globals, varname, w_newvalue) + + def DELETE_GLOBAL(self, nameindex, next_instr): + w_varname = self.getname_w(nameindex) + self.space.delitem(self.w_globals, w_varname) + + def LOAD_NAME(self, nameindex, next_instr): + if self.w_locals is not self.w_globals: + w_varname = self.getname_w(nameindex) + w_value = self.space.finditem(self.w_locals, w_varname) if w_value is not None: - f.pushvalue(w_value) + self.pushvalue(w_value) return - f.LOAD_GLOBAL(nameindex) # fall-back + self.LOAD_GLOBAL(nameindex, next_instr) # fall-back - def _load_global(f, varname): - w_value = f.space.finditem_str(f.w_globals, varname) + def _load_global(self, varname): + w_value = self.space.finditem_str(self.w_globals, varname) if w_value is None: # not in the globals, now look in the built-ins - w_value = f.get_builtin().getdictvalue(f.space, varname) + w_value = self.get_builtin().getdictvalue(self.space, varname) if w_value is None: - f._load_global_failed(varname) + self._load_global_failed(varname) return w_value _load_global._always_inline_ = True - def _load_global_failed(f, varname): + def _load_global_failed(self, varname): message = "global name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, message, varname) + raise operationerrfmt(self.space.w_NameError, message, varname) _load_global_failed._dont_inline_ = True - def LOAD_GLOBAL(f, nameindex, *ignored): - f.pushvalue(f._load_global(f.getname_u(nameindex))) + def LOAD_GLOBAL(self, nameindex, next_instr): + self.pushvalue(self._load_global(self.getname_u(nameindex))) LOAD_GLOBAL._always_inline_ = True - def DELETE_FAST(f, varindex, *ignored): - if f.fastlocals_w[varindex] is None: - varname = f.getlocalvarname(varindex) + def DELETE_FAST(self, varindex, next_instr): + if self.fastlocals_w[varindex] is None: + varname = self.getlocalvarname(varindex) message = "local variable '%s' referenced before assignment" - raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) - f.fastlocals_w[varindex] = None - - - def BUILD_TUPLE(f, itemcount, *ignored): - items = f.popvalues(itemcount) - w_tuple = f.space.newtuple(items) - f.pushvalue(w_tuple) - - def BUILD_LIST(f, itemcount, *ignored): - items = f.popvalues_mutable(itemcount) - w_list = f.space.newlist(items) - f.pushvalue(w_list) + raise operationerrfmt(self.space.w_UnboundLocalError, message, + varname) + self.fastlocals_w[varindex] = None + + def BUILD_TUPLE(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_tuple = self.space.newtuple(items) + self.pushvalue(w_tuple) + + def BUILD_LIST(self, itemcount, next_instr): + items = self.popvalues_mutable(itemcount) + w_list = self.space.newlist(items) + self.pushvalue(w_list) - def BUILD_MAP(f, itemcount, *ignored): + def BUILD_MAP(self, itemcount, next_instr): if not we_are_translated() and sys.version_info >= (2, 6): # We could pre-allocate a dict here # but for the moment this code is not translated. @@ -684,77 +676,92 @@ else: if itemcount != 0: raise BytecodeCorruption - w_dict = f.space.newdict() - f.pushvalue(w_dict) + w_dict = self.space.newdict() + self.pushvalue(w_dict) - def STORE_MAP(f, zero, *ignored): + def STORE_MAP(self, zero, next_instr): if not we_are_translated() and sys.version_info >= (2, 6): - w_key = f.popvalue() - w_value = f.popvalue() - w_dict = f.peekvalue() - f.space.setitem(w_dict, w_key, w_value) + w_key = self.popvalue() + w_value = self.popvalue() + w_dict = self.peekvalue() + self.space.setitem(w_dict, w_key, w_value) else: raise BytecodeCorruption - def LOAD_ATTR(f, nameindex, *ignored): + def LOAD_ATTR(self, nameindex, next_instr): "obj.attributename" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - w_value = f.space.getattr(w_obj, w_attributename) - f.pushvalue(w_value) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(f, w_1, w_2): return f.space.lt(w_1, w_2) - def cmp_le(f, w_1, w_2): return f.space.le(w_1, w_2) - def cmp_eq(f, w_1, w_2): return f.space.eq(w_1, w_2) - def cmp_ne(f, w_1, w_2): return f.space.ne(w_1, w_2) - def cmp_gt(f, w_1, w_2): return f.space.gt(w_1, w_2) - def cmp_ge(f, w_1, w_2): return f.space.ge(w_1, w_2) - - def cmp_in(f, w_1, w_2): - return f.space.contains(w_2, w_1) - def cmp_not_in(f, w_1, w_2): - return f.space.not_(f.space.contains(w_2, w_1)) - def cmp_is(f, w_1, w_2): - return f.space.is_(w_1, w_2) - def cmp_is_not(f, w_1, w_2): - return f.space.not_(f.space.is_(w_1, w_2)) - def cmp_exc_match(f, w_1, w_2): - return f.space.newbool(f.space.exception_match(w_1, w_2)) - - def COMPARE_OP(f, testnum, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() + def cmp_lt(self, w_1, w_2): + return self.space.lt(w_1, w_2) + + def cmp_le(self, w_1, w_2): + return self.space.le(w_1, w_2) + + def cmp_eq(self, w_1, w_2): + return self.space.eq(w_1, w_2) + + def cmp_ne(self, w_1, w_2): + return self.space.ne(w_1, w_2) + + def cmp_gt(self, w_1, w_2): + return self.space.gt(w_1, w_2) + + def cmp_ge(self, w_1, w_2): + return self.space.ge(w_1, w_2) + + def cmp_in(self, w_1, w_2): + return self.space.contains(w_2, w_1) + + def cmp_not_in(self, w_1, w_2): + return self.space.not_(self.space.contains(w_2, w_1)) + + def cmp_is(self, w_1, w_2): + return self.space.is_(w_1, w_2) + + def cmp_is_not(self, w_1, w_2): + return self.space.not_(self.space.is_(w_1, w_2)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() w_result = None for i, attr in unrolling_compare_dispatch_table: if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) + w_result = getattr(self, attr)(w_1, w_2) break else: raise BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) + self.pushvalue(w_result) - def IMPORT_NAME(f, nameindex, *ignored): - space = f.space - w_modulename = f.getname_w(nameindex) - modulename = f.space.str_w(w_modulename) - w_fromlist = f.popvalue() + def IMPORT_NAME(self, nameindex, next_instr): + space = self.space + w_modulename = self.getname_w(nameindex) + modulename = self.space.str_w(w_modulename) + w_fromlist = self.popvalue() # CPython 2.5 adds an extra argument consumed by this opcode - if f.pycode.magic >= 0xa0df294: - w_flag = f.popvalue() + if self.pycode.magic >= 0xa0df294: + w_flag = self.popvalue() else: w_flag = None - w_import = f.get_builtin().getdictvalue(f.space, '__import__') + w_import = self.get_builtin().getdictvalue(space, '__import__') if w_import is None: raise OperationError(space.w_ImportError, space.wrap("__import__ not found")) - w_locals = f.w_locals + w_locals = self.w_locals if w_locals is None: # CPython does this w_locals = space.w_None w_modulename = space.wrap(modulename) - w_globals = f.w_globals + w_globals = self.w_globals if w_flag is None: w_obj = space.call_function(w_import, w_modulename, w_globals, w_locals, w_fromlist) @@ -762,79 +769,79 @@ w_obj = space.call_function(w_import, w_modulename, w_globals, w_locals, w_fromlist, w_flag) - f.pushvalue(w_obj) + self.pushvalue(w_obj) - def IMPORT_STAR(f, *ignored): - w_module = f.popvalue() - w_locals = f.getdictscope() - import_all_from(f.space, w_module, w_locals) - f.setdictscope(w_locals) - - def IMPORT_FROM(f, nameindex, *ignored): - w_name = f.getname_w(nameindex) - w_module = f.peekvalue() + def IMPORT_STAR(self, oparg, next_instr): + w_module = self.popvalue() + w_locals = self.getdictscope() + import_all_from(self.space, w_module, w_locals) + self.setdictscope(w_locals) + + def IMPORT_FROM(self, nameindex, next_instr): + w_name = self.getname_w(nameindex) + w_module = self.peekvalue() try: - w_obj = f.space.getattr(w_module, w_name) + w_obj = self.space.getattr(w_module, w_name) except OperationError, e: - if not e.match(f.space, f.space.w_AttributeError): + if not e.match(self.space, self.space.w_AttributeError): raise - raise operationerrfmt(f.space.w_ImportError, + raise operationerrfmt(self.space.w_ImportError, "cannot import name '%s'", - f.space.str_w(w_name)) - f.pushvalue(w_obj) + self.space.str_w(w_name)) + self.pushvalue(w_obj) - def JUMP_ABSOLUTE(f, jumpto, next_instr): + def JUMP_ABSOLUTE(self, jumpto, next_instr): return jumpto - def JUMP_FORWARD(f, jumpby, next_instr, *ignored): + def JUMP_FORWARD(self, jumpby, next_instr): next_instr += jumpby return next_instr - def JUMP_IF_FALSE(f, stepby, next_instr, *ignored): - w_cond = f.peekvalue() - if not f.space.is_true(w_cond): + def JUMP_IF_FALSE(self, stepby, next_instr): + w_cond = self.peekvalue() + if not self.space.is_true(w_cond): next_instr += stepby return next_instr - def JUMP_IF_TRUE(f, stepby, next_instr, *ignored): - w_cond = f.peekvalue() - if f.space.is_true(w_cond): + def JUMP_IF_TRUE(self, stepby, next_instr): + w_cond = self.peekvalue() + if self.space.is_true(w_cond): next_instr += stepby return next_instr - def GET_ITER(f, *ignored): - w_iterable = f.popvalue() - w_iterator = f.space.iter(w_iterable) - f.pushvalue(w_iterator) + def GET_ITER(self, oparg, next_instr): + w_iterable = self.popvalue() + w_iterator = self.space.iter(w_iterable) + self.pushvalue(w_iterator) - def FOR_ITER(f, jumpby, next_instr, *ignored): - w_iterator = f.peekvalue() + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() try: - w_nextitem = f.space.next(w_iterator) + w_nextitem = self.space.next(w_iterator) except OperationError, e: - if not e.match(f.space, f.space.w_StopIteration): - raise + if not e.match(self.space, self.space.w_StopIteration): + raise # iterator exhausted - f.popvalue() + self.popvalue() next_instr += jumpby else: - f.pushvalue(w_nextitem) + self.pushvalue(w_nextitem) return next_instr - def FOR_LOOP(f, oparg, *ignored): + def FOR_LOOP(self, oparg, next_instr): raise BytecodeCorruption, "old opcode, no longer in use" - def SETUP_LOOP(f, offsettoend, next_instr, *ignored): - block = LoopBlock(f, next_instr + offsettoend) - f.append_block(block) - - def SETUP_EXCEPT(f, offsettoend, next_instr, *ignored): - block = ExceptBlock(f, next_instr + offsettoend) - f.append_block(block) - - def SETUP_FINALLY(f, offsettoend, next_instr, *ignored): - block = FinallyBlock(f, next_instr + offsettoend) - f.append_block(block) + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend) + self.append_block(block) + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend) + self.append_block(block) + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend) + self.append_block(block) def END_FINALLY(self, oparg, next_instr): unroller = self.end_finally() @@ -849,27 +856,27 @@ next_instr = block.handle(self, unroller) return next_instr - def WITH_CLEANUP(f, *ignored): + def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - w_exitfunc = f.popvalue() - w_unroller = f.peekvalue(2) - unroller = f.space.interpclass_w(w_unroller) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(2) + unroller = self.space.interpclass_w(w_unroller) if isinstance(unroller, SApplicationException): operr = unroller.operr - w_result = f.space.call_function(w_exitfunc, - operr.w_type, - operr.get_w_value(f.space), - operr.application_traceback) - if f.space.is_true(w_result): + w_result = self.space.call_function(w_exitfunc, + operr.w_type, + operr.get_w_value(self.space), + operr.application_traceback) + if self.space.is_true(w_result): # __exit__() returned True -> Swallow the exception. - f.settopvalue(f.space.w_None, 2) + self.settopvalue(self.space.w_None, 2) else: - f.space.call_function(w_exitfunc, - f.space.w_None, - f.space.w_None, - f.space.w_None) + self.space.call_function(w_exitfunc, + self.space.w_None, + self.space.w_None, + self.space.w_None) - def YIELD_VALUE(f, oparg, next_instr): + def YIELD_VALUE(self, oparg, next_instr): raise Yield def RETURN_VALUE(self, oparg, next_instr): @@ -884,7 +891,7 @@ @jit.unroll_safe - def call_function(f, oparg, w_star=None, w_starstar=None): + def call_function(self, oparg, w_star=None, w_starstar=None): from pypy.rlib import rstack # for resume points from pypy.interpreter.function import is_builtin_code @@ -897,126 +904,121 @@ n_keywords -= 1 if n_keywords < 0: break - w_value = f.popvalue() - w_key = f.popvalue() - key = f.space.str_w(w_key) + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) keywords[n_keywords] = key keywords_w[n_keywords] = w_value else: keywords = None keywords_w = None - arguments = f.popvalues(n_arguments) - args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) - w_function = f.popvalue() - if f.is_being_profiled and is_builtin_code(w_function): - w_result = f.space.call_args_and_c_profile(f, w_function, args) + arguments = self.popvalues(n_arguments) + args = self.argument_factory(arguments, keywords, keywords_w, w_star, + w_starstar) + w_function = self.popvalue() + if self.is_being_profiled and is_builtin_code(w_function): + w_result = self.space.call_args_and_c_profile(self, 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) - - def CALL_FUNCTION(f, oparg, *ignored): + w_result = self.space.call_args(w_function, args) + rstack.resume_point("call_function", self, returns=w_result) + self.pushvalue(w_result) + + def CALL_FUNCTION(self, oparg, next_instr): from pypy.rlib import rstack # for resume points # XXX start of hack for performance if (oparg >> 8) & 0xff == 0: # Only positional arguments nargs = oparg & 0xff - w_function = f.peekvalue(nargs) + w_function = self.peekvalue(nargs) try: - w_result = f.space.call_valuestack(w_function, nargs, f) - rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) + w_result = self.space.call_valuestack(w_function, nargs, self) + rstack.resume_point("CALL_FUNCTION", self, nargs, + returns=w_result) finally: - f.dropvalues(nargs + 1) - f.pushvalue(w_result) + self.dropvalues(nargs + 1) + self.pushvalue(w_result) # XXX end of hack for performance else: # general case - f.call_function(oparg) + self.call_function(oparg) - def CALL_FUNCTION_VAR(f, oparg, *ignored): - w_varargs = f.popvalue() - f.call_function(oparg, w_varargs) - - def CALL_FUNCTION_KW(f, oparg, *ignored): - w_varkw = f.popvalue() - f.call_function(oparg, None, w_varkw) - - def CALL_FUNCTION_VAR_KW(f, oparg, *ignored): - w_varkw = f.popvalue() - w_varargs = f.popvalue() - f.call_function(oparg, w_varargs, w_varkw) - - def MAKE_FUNCTION(f, numdefaults, *ignored): - w_codeobj = f.popvalue() - codeobj = f.space.interp_w(PyCode, w_codeobj) - defaultarguments = f.popvalues(numdefaults) - fn = function.Function(f.space, codeobj, f.w_globals, defaultarguments) - f.pushvalue(f.space.wrap(fn)) + def CALL_FUNCTION_VAR(self, oparg, next_instr): + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs) + + def CALL_FUNCTION_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + self.call_function(oparg, None, w_varkw) + + def CALL_FUNCTION_VAR_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs, w_varkw) + + def MAKE_FUNCTION(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + codeobj = self.space.interp_w(PyCode, w_codeobj) + defaultarguments = self.popvalues(numdefaults) + fn = function.Function(self.space, codeobj, self.w_globals, + defaultarguments) + self.pushvalue(self.space.wrap(fn)) - def BUILD_SLICE(f, numargs, *ignored): + def BUILD_SLICE(self, numargs, next_instr): if numargs == 3: - w_step = f.popvalue() + w_step = self.popvalue() elif numargs == 2: - w_step = f.space.w_None + w_step = self.space.w_None else: raise BytecodeCorruption - w_end = f.popvalue() - w_start = f.popvalue() - w_slice = f.space.newslice(w_start, w_end, w_step) - f.pushvalue(w_slice) - - def LIST_APPEND(f, *ignored): - w = f.popvalue() - v = f.popvalue() - f.space.call_method(v, 'append', w) + w_end = self.popvalue() + w_start = self.popvalue() + w_slice = self.space.newslice(w_start, w_end, w_step) + self.pushvalue(w_slice) + + def LIST_APPEND(self, oparg, next_instr): + w = self.popvalue() + v = self.popvalue() + self.space.call_method(v, 'append', w) - def SET_LINENO(f, lineno, *ignored): + def SET_LINENO(self, lineno, next_instr): pass - def CALL_LIKELY_BUILTIN(f, oparg, *ignored): + def CALL_LIKELY_BUILTIN(self, oparg, next_instr): # overridden by faster version in the standard object space. from pypy.module.__builtin__ import OPTIMIZED_BUILTINS varname = OPTIMIZED_BUILTINS[oparg >> 8] - w_function = f._load_global(varname) + w_function = self._load_global(varname) nargs = oparg&0xFF try: - w_result = f.space.call_valuestack(w_function, nargs, f) + w_result = self.space.call_valuestack(w_function, nargs, self) finally: - f.dropvalues(nargs) - f.pushvalue(w_result) + self.dropvalues(nargs) + self.pushvalue(w_result) - def LOOKUP_METHOD(f, nameindex, *ignored): + def LOOKUP_METHOD(self, nameindex, next_instr): # overridden by faster version in the standard object space. - space = f.space - w_obj = f.popvalue() - w_name = f.getname_w(nameindex) + space = self.space + w_obj = slef.popvalue() + w_name = self.getname_w(nameindex) w_value = space.getattr(w_obj, w_name) - f.pushvalue(w_value) - #f.pushvalue(None) + self.pushvalue(w_value) - def CALL_METHOD(f, nargs, *ignored): + def CALL_METHOD(self, nargs, next_instr): # overridden by faster version in the standard object space. # 'nargs' is the argument count excluding the implicit 'self' - w_callable = f.peekvalue(nargs) + w_callable = self.peekvalue(nargs) try: - w_result = f.space.call_valuestack(w_callable, nargs, f) + w_result = self.space.call_valuestack(w_callable, nargs, self) finally: - f.dropvalues(nargs + 1) - f.pushvalue(w_result) + self.dropvalues(nargs + 1) + self.pushvalue(w_result) -## def EXTENDED_ARG(f, oparg, *ignored): -## opcode = f.nextop() -## oparg = oparg<<16 | f.nextarg() -## fn = f.dispatch_table_w_arg[opcode] -## if fn is None: -## raise BytecodeCorruption -## fn(f, oparg) - - def MISSING_OPCODE(f, oparg, next_instr, *ignored): + def MISSING_OPCODE(self, oparg, next_instr): ofs = next_instr - 1 - c = f.pycode.co_code[ofs] - name = f.pycode.co_name + c = self.pycode.co_code[ofs] + name = self.pycode.co_name raise BytecodeCorruption("unknown opcode, ofs=%d, code=%d, name=%s" % (ofs, ord(c), name) ) @@ -1255,9 +1257,9 @@ """ applevel implementation of certain system properties, imports and other helpers""" import sys - + def sys_stdout(): - try: + try: return sys.stdout except AttributeError: raise RuntimeError("lost sys.stdout") @@ -1277,7 +1279,7 @@ # add a softspace unless we just printed a string which ends in a '\t' # or '\n' -- or more generally any whitespace character but ' ' if isinstance(x, str) and x and x[-1].isspace() and x[-1]!=' ': - return + return # XXX add unicode handling file_softspace(stream, True) print_item_to._annspecialcase_ = "specialize:argtype(0)" @@ -1326,10 +1328,10 @@ return type(base) elif '__metaclass__' in globals: return globals['__metaclass__'] - else: - try: - return builtin.__metaclass__ - except AttributeError: + else: + try: + return builtin.__metaclass__ + except AttributeError: return type ''', filename=__file__) From benjamin at codespeak.net Fri Mar 26 04:18:32 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 04:18:32 +0100 (CET) Subject: [pypy-svn] r72875 - in pypy/trunk/pypy: interpreter module/pypyjit Message-ID: <20100326031832.65373282BE4@codespeak.net> Author: benjamin Date: Fri Mar 26 04:18:30 2010 New Revision: 72875 Modified: pypy/trunk/pypy/interpreter/pyopcode.py pypy/trunk/pypy/module/pypyjit/interp_jit.py Log: re add JUMP_ABSOLUTE special ec argument Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 04:18:30 2010 @@ -206,6 +206,10 @@ next_instr += 3 oparg = (oparg << 16) | (hi << 8) | lo + if opcode == opcodedesc.JUMP_ABSOLUTE.index: + # Special case for the JIT + return self.jump_absolute(oparg, next_instr, ec) + if we_are_translated(): from pypy.rlib import rstack # for resume points @@ -790,7 +794,7 @@ self.space.str_w(w_name)) self.pushvalue(w_obj) - def JUMP_ABSOLUTE(self, jumpto, next_instr): + def jump_absolute(self, jumpto, next_instr, ec): return jumpto def JUMP_FORWARD(self, jumpby, next_instr): Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Fri Mar 26 04:18:30 2010 @@ -78,7 +78,7 @@ except ExitFrame: return self.popvalue() - def JUMP_ABSOLUTE(f, jumpto, _, ec=None): + def jump_absolute(self, jumpto, _, ec=None): if we_are_jitted(): f.last_instr = intmask(jumpto) ec.bytecode_trace(f) From benjamin at codespeak.net Fri Mar 26 04:21:49 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 04:21:49 +0100 (CET) Subject: [pypy-svn] r72876 - pypy/trunk/pypy/module/pypyjit Message-ID: <20100326032149.94D21282BE4@codespeak.net> Author: benjamin Date: Fri Mar 26 04:21:48 2010 New Revision: 72876 Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py Log: fix names Modified: pypy/trunk/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/trunk/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/trunk/pypy/module/pypyjit/interp_jit.py Fri Mar 26 04:21:48 2010 @@ -80,11 +80,11 @@ def jump_absolute(self, jumpto, _, ec=None): if we_are_jitted(): - f.last_instr = intmask(jumpto) - ec.bytecode_trace(f) - jumpto = r_uint(f.last_instr) - pypyjitdriver.can_enter_jit(frame=f, ec=ec, next_instr=jumpto, - pycode=f.getcode()) + self.last_instr = intmask(jumpto) + ec.bytecode_trace(self) + jumpto = r_uint(self.last_instr) + pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto, + pycode=self.getcode()) return jumpto From fijal at codespeak.net Fri Mar 26 04:42:11 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 04:42:11 +0100 (CET) Subject: [pypy-svn] r72877 - in pypy/trunk/pypy/jit/backend/llsupport: . test Message-ID: <20100326034211.5E60C282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 04:42:09 2010 New Revision: 72877 Added: pypy/trunk/pypy/jit/backend/llsupport/support.py - copied unchanged from r72876, pypy/branch/kill-asm-call/pypy/jit/backend/llsupport/support.py Modified: pypy/trunk/pypy/jit/backend/llsupport/descr.py pypy/trunk/pypy/jit/backend/llsupport/gc.py pypy/trunk/pypy/jit/backend/llsupport/llmodel.py pypy/trunk/pypy/jit/backend/llsupport/test/test_descr.py pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Log: Merge the kill-asm-call branch. This branch implements calls as small stubs that gets rendered as C calls instead of small assembler stubs. Mostly a cleanup, but also might be slightly memory and cpu friendly. Modified: pypy/trunk/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/descr.py Fri Mar 26 04:42:09 2010 @@ -1,7 +1,9 @@ -from pypy.rpython.lltypesystem import lltype -from pypy.jit.backend.llsupport import symbolic +import py +from pypy.rpython.lltypesystem import lltype, rffi, llmemory +from pypy.jit.backend.llsupport import symbolic, support from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat +from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances @@ -11,8 +13,9 @@ class GcCache(object): - def __init__(self, translate_support_code): + def __init__(self, translate_support_code, rtyper=None): self.translate_support_code = translate_support_code + self.rtyper = rtyper self._cache_size = {} self._cache_field = {} self._cache_array = {} @@ -176,6 +179,7 @@ # CallDescrs class BaseCallDescr(AbstractDescr): + empty_box = BoxInt(0) _clsname = '' loop_token = None arg_classes = '' # <-- annotation hack @@ -187,17 +191,9 @@ def get_extra_info(self): return self.extrainfo - def instantiate_arg_classes(self): - result = [] - for c in self.arg_classes: - if c == 'i': box = BoxInt() - elif c == 'f': box = BoxFloat() - else: box = BoxPtr() - result.append(box) - return result - _returns_a_pointer = False # unless overridden by GcPtrCallDescr _returns_a_float = False # unless overridden by FloatCallDescr + _returns_a_void = False # unless overridden by VoidCallDescr def returns_a_pointer(self): return self._returns_a_pointer @@ -205,39 +201,59 @@ def returns_a_float(self): return self._returns_a_float + def returns_a_void(self): + return self._returns_a_void + def get_result_size(self, translate_support_code): raise NotImplementedError - def get_token_for_call(self, cpu): - if self.loop_token is not None: - return self.loop_token - args = [BoxInt()] + self.instantiate_arg_classes() - if self.get_result_size(cpu.translate_support_code) == 0: - result = None - result_list = [] - else: - if self.returns_a_pointer(): - result = BoxPtr() - elif self.returns_a_float(): - result = BoxFloat() + def get_call_stub(self): + return self.call_stub + + def create_call_stub(self, rtyper, RESULT): + def process(no, c): + if c == 'i': + return 'args[%d].getint()' % (no,) + elif c == 'f': + return 'args[%d].getfloat()' % (no,) + elif c == 'r': + return 'args[%d].getref_base()' % (no,) else: - result = BoxInt() - result_list = [result] - operations = [ - ResOperation(rop.CALL, args[:], result, self), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None, - descr=BasicFailDescr()), - ResOperation(rop.FINISH, result_list, None, - descr=BasicFailDescr())] - operations[1].fail_args = [] - loop_token = LoopToken() - # note: the 'args' that we pass below is not the same object as the - # 'args[:]' that was passed above to ResOperation, because we want - # the argument to ResOperation to be non-resizable, but the argument - # to compile_loop to be resizable. - cpu.compile_loop(args, operations, loop_token) - self.loop_token = loop_token - return loop_token + raise Exception("Unknown type %s for type %s" % (c, TP)) + + def TYPE(arg): + if arg == 'i': + return lltype.Signed + elif arg == 'f': + return lltype.Float + elif arg == 'r': + return llmemory.GCREF + elif arg == 'v': + return lltype.Void + + args = ", ".join([process(i + 1, c) for i, c in + enumerate(self.arg_classes)]) + + if self.returns_a_pointer(): + result = 'history.BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, res))' + elif self.returns_a_float(): + result = 'history.BoxFloat(res)' + elif self.returns_a_void(): + result = 'None' + else: + result = 'history.BoxInt(rffi.cast(lltype.Signed, res))' + source = py.code.Source(""" + def call_stub(args): + fnptr = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) + res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) + return %(result)s + """ % locals()) + ARGS = [TYPE(arg) for arg in self.arg_classes] + FUNC = lltype.FuncType(ARGS, RESULT) + d = locals().copy() + d.update(globals()) + exec source.compile() in d + self.call_stub = d['call_stub'] def repr_of_descr(self): return '<%s>' % self._clsname @@ -245,15 +261,20 @@ class NonGcPtrCallDescr(BaseCallDescr): _clsname = 'NonGcPtrCallDescr' + def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrCallDescr(NonGcPtrCallDescr): + empty_box = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) _clsname = 'GcPtrCallDescr' _returns_a_pointer = True class VoidCallDescr(NonGcPtrCallDescr): + empty_box = None _clsname = 'VoidCallDescr' + _returns_a_void = True + def get_result_size(self, translate_support_code): return 0 @@ -281,6 +302,7 @@ return cache[key] except KeyError: calldescr = cls(arg_classes, extrainfo) + calldescr.create_call_stub(gccache.rtyper, RESULT) cache[key] = calldescr return calldescr @@ -308,6 +330,7 @@ # if TYPE is lltype.Float: setattr(Descr, floatattrname, True) + Descr.empty_box = BoxFloat(0.0) # _cache[nameprefix, TYPE] = Descr return Descr Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/gc.py Fri Mar 26 04:42:09 2010 @@ -19,8 +19,8 @@ # ____________________________________________________________ class GcLLDescription(GcCache): - def __init__(self, gcdescr, translator=None): - GcCache.__init__(self, translator is not None) + def __init__(self, gcdescr, translator=None, rtyper=None): + GcCache.__init__(self, translator is not None, rtyper) self.gcdescr = gcdescr def _freeze_(self): return True @@ -41,8 +41,8 @@ moving_gc = False gcrootmap = None - def __init__(self, gcdescr, translator): - GcLLDescription.__init__(self, gcdescr, translator) + def __init__(self, gcdescr, translator, rtyper): + GcLLDescription.__init__(self, gcdescr, translator, rtyper) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() @@ -327,11 +327,11 @@ class GcLLDescr_framework(GcLLDescription): DEBUG = False # forced to True by x86/test/test_zrpy_gc.py - def __init__(self, gcdescr, translator, llop1=llop): + def __init__(self, gcdescr, translator, rtyper, llop1=llop): from pypy.rpython.memory.gctypelayout import _check_typeid from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.gctransform import framework - GcLLDescription.__init__(self, gcdescr, translator) + GcLLDescription.__init__(self, gcdescr, translator, rtyper) assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 @@ -611,7 +611,7 @@ # ____________________________________________________________ -def get_ll_description(gcdescr, translator=None): +def get_ll_description(gcdescr, translator=None, rtyper=None): # translator is None if translate_support_code is False. if gcdescr is not None: name = gcdescr.config.translation.gctransformer @@ -622,4 +622,4 @@ except KeyError: raise NotImplementedError("GC transformer %r not supported by " "the JIT backend" % (name,)) - return cls(gcdescr, translator) + return cls(gcdescr, translator, rtyper) Modified: pypy/trunk/pypy/jit/backend/llsupport/llmodel.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/llmodel.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/llmodel.py Fri Mar 26 04:42:09 2010 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.llinterp import LLInterpreter, LLException from pypy.rpython.annlowlevel import llhelper from pypy.rlib.objectmodel import we_are_translated, specialize from pypy.jit.metainterp.history import BoxInt, BoxPtr, set_future_values,\ @@ -13,6 +13,9 @@ from pypy.jit.backend.llsupport.descr import get_field_descr, BaseFieldDescr from pypy.jit.backend.llsupport.descr import get_array_descr, BaseArrayDescr from pypy.jit.backend.llsupport.descr import get_call_descr, BaseCallDescr +from pypy.rpython.annlowlevel import cast_instance_to_base_ptr + +empty_int_box = BoxInt(0) class AbstractLLCPU(AbstractCPU): from pypy.jit.metainterp.typesystem import llhelper as ts @@ -31,7 +34,7 @@ translator = rtyper.annotator.translator else: translator = None - self.gc_ll_descr = get_ll_description(gcdescr, translator) + self.gc_ll_descr = get_ll_description(gcdescr, translator, rtyper) if translator and translator.config.translation.gcremovetypeptr: self.vtable_offset = None else: @@ -474,20 +477,23 @@ if not we_are_translated(): assert (list(calldescr.arg_classes) == [arg.type for arg in args[1:]]) - loop_token = calldescr.get_token_for_call(self) - set_future_values(self, args) - self.execute_token(loop_token) - # Note: if an exception is set, the rest of the code does a bit of - # nonsense but nothing wrong (the return value should be ignored) - if calldescr.returns_a_pointer(): - return BoxPtr(self.get_latest_value_ref(0)) - elif calldescr.returns_a_float(): - return BoxFloat(self.get_latest_value_float(0)) - elif calldescr.get_result_size(self.translate_support_code) > 0: - return BoxInt(self.get_latest_value_int(0)) - else: - return None - + callstub = calldescr.get_call_stub() + try: + return callstub(args) + except Exception, e: + if not we_are_translated(): + if not type(e) is LLException: + raise + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + e.args[1]) + self.saved_exception = rffi.cast(lltype.Signed, e.args[0]) + else: + ptr = cast_instance_to_base_ptr(e) + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + ptr) + self.saved_exception = rffi.cast(lltype.Signed, ptr.typeptr) + return calldescr.empty_box + def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/test/test_descr.py Fri Mar 26 04:42:09 2010 @@ -2,7 +2,8 @@ from pypy.jit.backend.llsupport.descr import * from pypy.jit.backend.llsupport import symbolic from pypy.rlib.objectmodel import Symbolic - +from pypy.rpython.annlowlevel import llhelper +from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr def test_get_size_descr(): c0 = GcCache(False) @@ -147,6 +148,7 @@ assert not descr1.returns_a_pointer() assert not descr1.returns_a_float() assert descr1.arg_classes == "ii" + assert isinstance(descr1.empty_box, BoxInt) # T = lltype.GcStruct('T') descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) @@ -154,15 +156,22 @@ assert descr2.returns_a_pointer() assert not descr2.returns_a_float() assert descr2.arg_classes == "r" + assert isinstance(descr2.empty_box, BoxPtr) # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) # + V = lltype.Struct('V', ('x', lltype.Signed)) + assert isinstance(get_call_descr(c0, [], lltype.Ptr(V)).empty_box, BoxInt) + # + assert get_call_descr(c0, [], lltype.Void).empty_box is None + # descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float) assert descr4.get_result_size(False) == rffi.sizeof(lltype.Float) assert not descr4.returns_a_pointer() assert descr4.returns_a_float() assert descr4.arg_classes == "ff" + assert isinstance(descr4.empty_box, BoxFloat) def test_get_call_descr_translated(): c1 = GcCache(True) @@ -227,3 +236,34 @@ # descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float) assert 'FloatCallDescr' in descr4f.repr_of_descr() + +def test_call_stubs(): + c0 = GcCache(False) + ARGS = [lltype.Char, lltype.Signed] + RES = lltype.Char + descr1 = get_call_descr(c0, ARGS, RES) + def f(a, b): + return 'c' + + call_stub = descr1.get_call_stub() + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + + res = call_stub([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxInt(1), BoxInt(2)]) + assert res.getint() == ord('c') + + ARRAY = lltype.GcArray(lltype.Signed) + ARGS = [lltype.Float, lltype.Ptr(ARRAY)] + RES = lltype.Float + + def f(a, b): + return float(b[0]) + a + + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + descr2 = get_call_descr(c0, ARGS, RES) + a = lltype.malloc(ARRAY, 3) + opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) + a[0] = 1 + res = descr2.get_call_stub()([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxFloat(3.5), BoxPtr(opaquea)]) + assert res.getfloat() == 4.5 Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py Fri Mar 26 04:42:09 2010 @@ -9,7 +9,7 @@ def test_boehm(): - gc_ll_descr = GcLLDescr_boehm(None, None) + gc_ll_descr = GcLLDescr_boehm(None, None, None) # record = [] prev_funcptr_for_new = gc_ll_descr.funcptr_for_new @@ -167,7 +167,8 @@ gcdescr = get_description(config_) translator = FakeTranslator() llop1 = FakeLLOp() - gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), None, + llop1) gc_ll_descr.initialize() self.llop1 = llop1 self.gc_ll_descr = gc_ll_descr From fijal at codespeak.net Fri Mar 26 04:42:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 04:42:30 +0100 (CET) Subject: [pypy-svn] r72878 - pypy/branch/kill-asm-call Message-ID: <20100326034230.94253282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 04:42:29 2010 New Revision: 72878 Removed: pypy/branch/kill-asm-call/ Log: Kill merged branch From fijal at codespeak.net Fri Mar 26 04:43:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 04:43:26 +0100 (CET) Subject: [pypy-svn] r72879 - pypy/branch/blackhole-improvement Message-ID: <20100326034326.95815282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 04:43:25 2010 New Revision: 72879 Removed: pypy/branch/blackhole-improvement/ Log: Remove branch, will branch again From fijal at codespeak.net Fri Mar 26 04:44:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 04:44:26 +0100 (CET) Subject: [pypy-svn] r72880 - pypy/branch/blackhole-improvement Message-ID: <20100326034426.03A8F282BE4@codespeak.net> Author: fijal Date: Fri Mar 26 04:44:24 2010 New Revision: 72880 Added: pypy/branch/blackhole-improvement/ - copied from r72879, pypy/trunk/ Log: A branch to improve blackhole (another attempt) From benjamin at codespeak.net Fri Mar 26 04:45:08 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 04:45:08 +0100 (CET) Subject: [pypy-svn] r72881 - pypy/trunk/pypy/interpreter Message-ID: <20100326034508.7088B282BE4@codespeak.net> Author: benjamin Date: Fri Mar 26 04:45:06 2010 New Revision: 72881 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: revert r72871 as it had the effect of breaking stackless in some obscure way Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 04:45:06 2010 @@ -206,8 +206,35 @@ next_instr += 3 oparg = (oparg << 16) | (hi << 8) | lo + if opcode == opcodedesc.RETURN_VALUE.index: + w_returnvalue = self.popvalue() + block = self.unrollstack(SReturnValue.kind) + if block is None: + self.pushvalue(w_returnvalue) # XXX ping pong + raise Return + else: + unroller = SReturnValue(w_returnvalue) + next_instr = block.handle(self, unroller) + return next_instr # now inside a 'finally' block + + if opcode == opcodedesc.YIELD_VALUE.index: + #self.last_instr = intmask(next_instr - 1) XXX clean up! + raise Yield + + if opcode == opcodedesc.END_FINALLY.index: + unroller = self.end_finally() + if isinstance(unroller, SuspendedUnroller): + # go on unrolling the stack + block = self.unrollstack(unroller.kind) + if block is None: + w_result = unroller.nomoreblocks() + self.pushvalue(w_result) + raise Return + else: + next_instr = block.handle(self, unroller) + return next_instr + if opcode == opcodedesc.JUMP_ABSOLUTE.index: - # Special case for the JIT return self.jump_absolute(oparg, next_instr, ec) if we_are_translated(): @@ -218,7 +245,7 @@ if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): - continue # e.g. for JUMP_ABSOLUTE, implemented above + continue # e.g. for JUMP_FORWARD, implemented above if opcode == opdesc.index: # dispatch to the opcode method @@ -847,19 +874,6 @@ block = FinallyBlock(self, next_instr + offsettoend) self.append_block(block) - def END_FINALLY(self, oparg, next_instr): - unroller = self.end_finally() - if isinstance(unroller, SuspendedUnroller): - # go on unrolling the stack - block = self.unrollstack(unroller.kind) - if block is None: - w_result = unroller.nomoreblocks() - self.pushvalue(w_result) - raise Return - else: - next_instr = block.handle(self, unroller) - return next_instr - def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state w_exitfunc = self.popvalue() @@ -880,20 +894,6 @@ self.space.w_None, self.space.w_None) - def YIELD_VALUE(self, oparg, next_instr): - raise Yield - - def RETURN_VALUE(self, oparg, next_instr): - w_returnvalue = self.popvalue() - block = self.unrollstack(SReturnValue.kind) - if block is None: - self.pushvalue(w_returnvalue) - raise Return - unroller = SReturnValue(w_returnvalue) - next_instr = block.handle(self, unroller) - return next_instr # now inside a 'finally' block - - @jit.unroll_safe def call_function(self, oparg, w_star=None, w_starstar=None): from pypy.rlib import rstack # for resume points From benjamin at codespeak.net Fri Mar 26 04:45:39 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 04:45:39 +0100 (CET) Subject: [pypy-svn] r72882 - pypy/trunk/pypy/interpreter Message-ID: <20100326034539.6A6AF282BE4@codespeak.net> Author: benjamin Date: Fri Mar 26 04:45:38 2010 New Revision: 72882 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: fix comment Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 04:45:38 2010 @@ -245,7 +245,7 @@ if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): - continue # e.g. for JUMP_FORWARD, implemented above + continue # e.g. for JUMP_ABSOLUTE, implemented above if opcode == opdesc.index: # dispatch to the opcode method From arigo at codespeak.net Fri Mar 26 12:01:44 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 12:01:44 +0100 (CET) Subject: [pypy-svn] r72889 - pypy/trunk/pypy/interpreter Message-ID: <20100326110144.267C1282BEE@codespeak.net> Author: arigo Date: Fri Mar 26 12:01:42 2010 New Revision: 72889 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: Ah ah. Having some other test than pypy.objspace.flow detect this one would be kind of nice... Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Fri Mar 26 12:01:42 2010 @@ -1004,7 +1004,7 @@ def LOOKUP_METHOD(self, nameindex, next_instr): # overridden by faster version in the standard object space. space = self.space - w_obj = slef.popvalue() + w_obj = self.popvalue() w_name = self.getname_w(nameindex) w_value = space.getattr(w_obj, w_name) self.pushvalue(w_value) From arigo at codespeak.net Fri Mar 26 12:03:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 12:03:17 +0100 (CET) Subject: [pypy-svn] r72891 - pypy/trunk/pypy/translator/c/test Message-ID: <20100326110317.AC941282BEE@codespeak.net> Author: arigo Date: Fri Mar 26 12:03:16 2010 New Revision: 72891 Modified: pypy/trunk/pypy/translator/c/test/test_standalone.py Log: Skip the tests in TestMaemo until someone cares again. 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 Fri Mar 26 12:03:16 2010 @@ -590,6 +590,7 @@ class TestMaemo(TestStandalone): def setup_class(cls): + py.test.skip("TestMaemo: tests skipped for now") from pypy.translator.platform.maemo import check_scratchbox check_scratchbox() from pypy.config.pypyoption import get_pypy_config From arigo at codespeak.net Fri Mar 26 12:44:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 12:44:38 +0100 (CET) Subject: [pypy-svn] r72892 - in pypy/trunk/pypy: tool tool/test translator/platform Message-ID: <20100326114438.766C8282BEE@codespeak.net> Author: arigo Date: Fri Mar 26 12:44:36 2010 New Revision: 72892 Added: pypy/trunk/pypy/tool/runsubprocess.py (contents, props changed) pypy/trunk/pypy/tool/test/test_runsubprocess.py (contents, props changed) Modified: pypy/trunk/pypy/translator/platform/__init__.py Log: Workaround for the issue that os.fork() sometimes runs out of memory. Added: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/tool/runsubprocess.py Fri Mar 26 12:44:36 2010 @@ -0,0 +1,50 @@ +"""Run a subprocess. Wrapper around the 'subprocess' module +with a hack to prevent bogus out-of-memory conditions in os.fork() +if the current process already grew very large. +""" + +import sys, os +from subprocess import PIPE, Popen + +def run_subprocess(executable, args, env=None, cwd=None): + return _run(executable, args, env, cwd) + + +def _run(executable, args, env, cwd): # unless overridden below + 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, cwd=cwd) + stdout, stderr = pipe.communicate() + return pipe.returncode, stdout, stderr + + +if __name__ == '__main__': + while True: + operation = sys.stdin.readline() + if not operation: + sys.exit() + assert operation.startswith('(') + args = eval(operation) + results = _run(*args) + sys.stdout.write('%r\n' % (results,)) + sys.stdout.flush() + + +if sys.platform != 'win32' and hasattr(os, 'fork'): + # do this at import-time, when the process is still tiny + _child_stdin, _child_stdout = os.popen2( + "'%s' '%s'" % (sys.executable, os.path.abspath(__file__))) + + def _run(*args): + _child_stdin.write('%r\n' % (args,)) + _child_stdin.flush() + results = _child_stdout.readline() + assert results.startswith('(') + return eval(results) Added: pypy/trunk/pypy/tool/test/test_runsubprocess.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/tool/test/test_runsubprocess.py Fri Mar 26 12:44:36 2010 @@ -0,0 +1,26 @@ +import py, os +from pypy.tool.runsubprocess import run_subprocess + +def test_echo(): + if not os.path.exists('/bin/echo'): + py.test.skip("there is no /bin/echo") + returncode, stdout, stderr = run_subprocess('/bin/echo', 'FooBar') + assert returncode == 0 + assert stdout == 'FooBar\n' + assert stderr == '' + +def test_false(): + if not os.path.exists('/bin/false'): + py.test.skip("there is no /bin/false") + returncode, stdout, stderr = run_subprocess('/bin/false', []) + assert returncode == 1 + assert stdout == '' + assert stderr == '' + +def test_cat_fail(): + if not os.path.exists('/bin/cat'): + py.test.skip("there is no /bin/cat") + returncode, stdout, stderr = run_subprocess('/bin/cat', 'no/such/filename') + assert returncode == 1 + assert stdout == '' + assert 'no/such/filename' in stderr Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Fri Mar 26 12:44:36 2010 @@ -10,21 +10,7 @@ log = py.log.Producer("platform") py.log.setconsumer("platform", ansi_log) -from subprocess import PIPE, Popen - -def _run_subprocess(executable, args, env=None, cwd=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, cwd=cwd) - stdout, stderr = pipe.communicate() - return pipe.returncode, stdout, stderr +from pypy.tool.runsubprocess import run_subprocess as _run_subprocess class CompilationError(Exception): def __init__(self, out, err): From arigo at codespeak.net Fri Mar 26 13:18:00 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 13:18:00 +0100 (CET) Subject: [pypy-svn] r72893 - pypy/trunk/pypy/module/_minimal_curses Message-ID: <20100326121800.A1544282BE4@codespeak.net> Author: arigo Date: Fri Mar 26 13:17:58 2010 New Revision: 72893 Modified: pypy/trunk/pypy/module/_minimal_curses/__init__.py Log: Skip _curses tests, e.g. on Windows. Modified: pypy/trunk/pypy/module/_minimal_curses/__init__.py ============================================================================== --- pypy/trunk/pypy/module/_minimal_curses/__init__.py (original) +++ pypy/trunk/pypy/module/_minimal_curses/__init__.py Fri Mar 26 13:17:58 2010 @@ -1,7 +1,10 @@ try: import _curses except ImportError: - import _minimal_curses as _curses # when running on top of pypy-c + try: + import _minimal_curses as _curses # when running on top of pypy-c + except ImportError: + import py; py.test.skip("no _curses module") # no _curses at all from pypy.interpreter.mixedmodule import MixedModule from pypy.module._minimal_curses import fficurses From arigo at codespeak.net Fri Mar 26 14:18:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 14:18:27 +0100 (CET) Subject: [pypy-svn] r72894 - pypy/trunk/pypy/module/pyexpat/test Message-ID: <20100326131827.5FDD9282BEF@codespeak.net> Author: arigo Date: Fri Mar 26 14:18:25 2010 New Revision: 72894 Modified: pypy/trunk/pypy/module/pyexpat/test/test_build.py Log: Skip this test also if the interp-level module 'expat' is not there. Modified: pypy/trunk/pypy/module/pyexpat/test/test_build.py ============================================================================== --- pypy/trunk/pypy/module/pyexpat/test/test_build.py (original) +++ pypy/trunk/pypy/module/pyexpat/test/test_build.py Fri Mar 26 14:18:25 2010 @@ -4,8 +4,12 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.tool.rffi_platform import CompilationError -import os, pyexpat +import os import py +try: + import pyexpat +except ImportError: + py.test.skip("No module expat") try: from pypy.module.pyexpat import interp_pyexpat From arigo at codespeak.net Fri Mar 26 14:54:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 14:54:15 +0100 (CET) Subject: [pypy-svn] r72896 - pypy/trunk/pypy/rlib Message-ID: <20100326135415.BD47B282BEF@codespeak.net> Author: arigo Date: Fri Mar 26 14:54:14 2010 New Revision: 72896 Modified: pypy/trunk/pypy/rlib/rsocket.py Log: Initialize the family to the correct value. Avoids surprizes on Windows when calling a function that unexpectedly does not set the output address (e.g. recvfrom() on a connected IPv4 socket). Modified: pypy/trunk/pypy/rlib/rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/rsocket.py (original) +++ pypy/trunk/pypy/rlib/rsocket.py Fri Mar 26 14:54:14 2010 @@ -506,6 +506,10 @@ klass = familyclass(family) result = instantiate(klass) buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor='raw', zero=True) + # Initialize the family to the correct value. Avoids surprizes on + # Windows when calling a function that unexpectedly does not set + # the output address (e.g. recvfrom() on a connected IPv4 socket). + rffi.setintfield(rffi.cast(_c.sockaddr_ptr, buf), 'c_sa_family', family) result.setdata(buf, 0) return result, klass.maxlen From arigo at codespeak.net Fri Mar 26 15:22:55 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 15:22:55 +0100 (CET) Subject: [pypy-svn] r72898 - pypy/trunk/pypy/module/rctime/test Message-ID: <20100326142255.29784282BEF@codespeak.net> Author: arigo Date: Fri Mar 26 15:22:53 2010 New Revision: 72898 Modified: pypy/trunk/pypy/module/rctime/test/test_rctime.py Log: Add a test for some nonstandard extension. Modified: pypy/trunk/pypy/module/rctime/test/test_rctime.py ============================================================================== --- pypy/trunk/pypy/module/rctime/test/test_rctime.py (original) +++ pypy/trunk/pypy/module/rctime/test/test_rctime.py Fri Mar 26 15:22:53 2010 @@ -220,6 +220,14 @@ exp = '2000 01 01 00 00 00 1 001' assert rctime.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) == exp + def test_strftime_ext(self): + import time as rctime + + tt = rctime.gmtime() + result = rctime.strftime('%D', tt) + if result != '': # else format not supported and we got '' + assert result == rctime.strftime('%m/%d/%y', t) + def test_strftime_bounds_checking(self): import time as rctime From arigo at codespeak.net Fri Mar 26 15:23:30 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 15:23:30 +0100 (CET) Subject: [pypy-svn] r72899 - pypy/trunk/pypy/module/rctime Message-ID: <20100326142330.A75DF282BEF@codespeak.net> Author: arigo Date: Fri Mar 26 15:23:29 2010 New Revision: 72899 Modified: pypy/trunk/pypy/module/rctime/interp_time.py Log: Yeech! Forgot to lltype.free() the buffer in one case. Modified: pypy/trunk/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/trunk/pypy/module/rctime/interp_time.py (original) +++ pypy/trunk/pypy/module/rctime/interp_time.py Fri Mar 26 15:23:29 2010 @@ -452,20 +452,18 @@ i = 1024 while True: - outbuf = lltype.malloc(rffi.CCHARP.TO, i + 1, flavor='raw') - buflen = c_strftime(outbuf, i, format, buf_value) - - if buflen > 0 or i >= 256 * len(format): - # if the buffer is 256 times as long as the format, - # it's probably not failing for lack of room! - # More likely, the format yields an empty result, - # e.g. an empty format, or %Z when the timezone - # is unknown. - if buflen < 0: buflen = 0 # should not occur - outbuf[buflen] = '\x00' - result = rffi.charp2str(outbuf) + outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw') + try: + buflen = c_strftime(outbuf, i, format, buf_value) + if buflen > 0 or i >= 256 * len(format): + # if the buffer is 256 times as long as the format, + # it's probably not failing for lack of room! + # More likely, the format yields an empty result, + # e.g. an empty format, or %Z when the timezone + # is unknown. + result = rffi.charp2strn(outbuf, buflen) + return space.wrap(result) + finally: lltype.free(outbuf, flavor='raw') - return space.wrap(result) - i += i strftime.unwrap_spec = [ObjSpace, str, W_Root] From arigo at codespeak.net Fri Mar 26 15:43:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 15:43:47 +0100 (CET) Subject: [pypy-svn] r72900 - pypy/trunk/pypy/interpreter/test Message-ID: <20100326144347.41D34282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 15:43:45 2010 New Revision: 72900 Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py Log: Give up quoting on Windows. Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/test/test_executioncontext.py Fri Mar 26 15:43:45 2010 @@ -271,7 +271,11 @@ # would be called import os, sys print sys.executable, self.tmpfile - g = os.popen('"%s" "%s"' % (sys.executable, self.tmpfile), 'r') + if sys.platform == "win32": # quote? what's that? + cmdformat = "%s %s" + else: + cmdformat = "'%s' '%s'" + g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r') data = g.read() g.close() assert 'Called 1' in data From fijal at codespeak.net Fri Mar 26 15:54:00 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Fri, 26 Mar 2010 15:54:00 +0100 (CET) Subject: [pypy-svn] r72901 - pypy/benchmarks Message-ID: <20100326145400.31752282B9C@codespeak.net> Author: fijal Date: Fri Mar 26 15:53:58 2010 New Revision: 72901 Modified: pypy/benchmarks/runner.py Log: Update as per miquel's request Modified: pypy/benchmarks/runner.py ============================================================================== --- pypy/benchmarks/runner.py (original) +++ pypy/benchmarks/runner.py Fri Mar 26 15:53:58 2010 @@ -34,6 +34,7 @@ f.close() if upload: from saveresults import save + project = 'pypy' if "--jit threshold" in args: name = "pypy-c" else: @@ -43,11 +44,12 @@ name = "cpython" optionsname = "psyco-profile" revision = 262 + project = 'cpython' if force_host is not None: host = force_host else: host = socket.gethostname() - save('pypy', revision, res, options, branch, name, optionsname, host) + save(project, revision, res, options, branch, name, optionsname, host) BENCHMARK_SET = ['richards', 'slowspitfire', 'django', 'spambayes', 'rietveld', 'html5lib', 'ai'] From arigo at codespeak.net Fri Mar 26 16:03:20 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 16:03:20 +0100 (CET) Subject: [pypy-svn] r72902 - pypy/trunk/pypy/module/zipimport Message-ID: <20100326150320.CBEE5282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 16:03:19 2010 New Revision: 72902 Modified: pypy/trunk/pypy/module/zipimport/interp_zipimport.py Log: Fix for Windows. 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 Fri Mar 26 16:03:19 2010 @@ -326,10 +326,12 @@ w_ZipImportError = space.getattr(space.getbuiltinmodule('zipimport'), w('ZipImportError')) ok = False - parts = name.split(os.path.sep) + parts_ends = [i for i in range(0, len(name)) + if name[i] == os.path.sep or name[i] == ZIPSEP] + parts_ends.append(len(name)) filename = "" # make annotator happy - for i in range(1, len(parts) + 1): - filename = os.path.sep.join(parts[:i]) + for i in parts_ends: + filename = name[:i] if not filename: filename = os.path.sep try: From arigo at codespeak.net Fri Mar 26 16:09:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 16:09:04 +0100 (CET) Subject: [pypy-svn] r72903 - pypy/branch/fix-win Message-ID: <20100326150904.5A8DA282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 16:09:02 2010 New Revision: 72903 Added: pypy/branch/fix-win/ - copied from r72902, pypy/trunk/ Log: Move into a branch for fixing random Windows test failures. From arigo at codespeak.net Fri Mar 26 16:10:29 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 16:10:29 +0100 (CET) Subject: [pypy-svn] r72904 - pypy/branch/fix-win/pypy/module/zipimport/test Message-ID: <20100326151029.F19C9282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 16:10:28 2010 New Revision: 72904 Modified: pypy/branch/fix-win/pypy/module/zipimport/test/test_zipimport.py Log: Show py.test failures more clearly. Modified: pypy/branch/fix-win/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/branch/fix-win/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/branch/fix-win/pypy/module/zipimport/test/test_zipimport.py Fri Mar 26 16:10:28 2010 @@ -239,10 +239,11 @@ # value. Not sure why it doesn't the assertion uses import.archive # directly. -exarkun archive = importer.archive + realprefix = importer.prefix allbutlast = self.zipfile.split(os.path.sep)[:-1] prefix = 'directory' assert archive == self.zipfile - assert importer.prefix == prefix + assert realprefix == prefix def test_zip_directory_cache(self): """ Check full dictionary interface From arigo at codespeak.net Fri Mar 26 16:38:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 16:38:21 +0100 (CET) Subject: [pypy-svn] r72907 - in pypy/trunk/pypy/tool: . test Message-ID: <20100326153821.DFC00282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 16:38:20 2010 New Revision: 72907 Modified: pypy/trunk/pypy/tool/runsubprocess.py pypy/trunk/pypy/tool/test/test_runsubprocess.py Log: Correctly catch and re-raise exceptions, at least the ones inheriting from EnvironmentError. Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Fri Mar 26 16:38:20 2010 @@ -32,7 +32,10 @@ sys.exit() assert operation.startswith('(') args = eval(operation) - results = _run(*args) + try: + results = _run(*args) + except EnvironmentError, e: + results = (None, str(e)) sys.stdout.write('%r\n' % (results,)) sys.stdout.flush() @@ -47,4 +50,7 @@ _child_stdin.flush() results = _child_stdout.readline() assert results.startswith('(') - return eval(results) + results = eval(results) + if results[0] is None: + raise OSError(results[1]) + return results Modified: pypy/trunk/pypy/tool/test/test_runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/test/test_runsubprocess.py (original) +++ pypy/trunk/pypy/tool/test/test_runsubprocess.py Fri Mar 26 16:38:20 2010 @@ -1,6 +1,12 @@ import py, os from pypy.tool.runsubprocess import run_subprocess +def test_no_such_command(): + py.test.raises(EnvironmentError, run_subprocess, + 'this_command_does_not_exist', []) + py.test.raises(EnvironmentError, run_subprocess, + 'this_command_does_not_exist', []) + def test_echo(): if not os.path.exists('/bin/echo'): py.test.skip("there is no /bin/echo") From arigo at codespeak.net Fri Mar 26 16:52:23 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 16:52:23 +0100 (CET) Subject: [pypy-svn] r72908 - pypy/branch/fix-win/pypy/interpreter/test Message-ID: <20100326155223.21624282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 16:52:21 2010 New Revision: 72908 Modified: pypy/branch/fix-win/pypy/interpreter/test/test_executioncontext.py pypy/branch/fix-win/pypy/interpreter/test/test_zpy.py Log: Add quotes for Windows. Expected format: ""program" "arg1" "arg2"" Modified: pypy/branch/fix-win/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/fix-win/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/fix-win/pypy/interpreter/test/test_executioncontext.py Fri Mar 26 16:52:21 2010 @@ -271,8 +271,8 @@ # would be called import os, sys print sys.executable, self.tmpfile - if sys.platform == "win32": # quote? what's that? - cmdformat = "%s %s" + if sys.platform == "win32": + cmdformat = '""%s" "%s""' # excellent! tons of "! else: cmdformat = "'%s' '%s'" g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r') Modified: pypy/branch/fix-win/pypy/interpreter/test/test_zpy.py ============================================================================== --- pypy/branch/fix-win/pypy/interpreter/test/test_zpy.py (original) +++ pypy/branch/fix-win/pypy/interpreter/test/test_zpy.py Fri Mar 26 16:52:21 2010 @@ -6,17 +6,23 @@ pypypath = py.path.local(pypy.__file__).dirpath("bin", "py.py") +def cmdexec(s): + if sys.platform == 'win32': + s = '"%s"' % s # double double quotes + return py.process.cmdexec(s) + + def test_executable(): """Ensures sys.executable points to the py.py script""" # TODO : watch out for spaces/special chars in pypypath - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % - (sys.executable, pypypath) ) + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % + (sys.executable, pypypath) ) assert output.splitlines()[-1] == pypypath def test_special_names(): """Test the __name__ and __file__ special global names""" cmd = "print __name__; print '__file__' in globals()" - output = py.process.cmdexec( '''"%s" "%s" -c "%s" ''' % + output = cmdexec( '''"%s" "%s" -c "%s" ''' % (sys.executable, pypypath, cmd) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == 'False' @@ -26,7 +32,7 @@ tmpfile.write("print __name__; print __file__\n") tmpfile.close() - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == str(tmpfilepath) @@ -34,17 +40,17 @@ def test_argv_command(): """Some tests on argv""" # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c']) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) @@ -59,17 +65,17 @@ tmpfile.close() # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath]) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" "%s" hello''' % + output = cmdexec( '''"%s" "%s" "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O "%s" hello''' % + output = cmdexec( '''"%s" "%s" -O "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) @@ -94,7 +100,7 @@ e = None try: - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) except py.process.cmdexec.Error, e: pass From xoraxax at codespeak.net Fri Mar 26 16:58:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Fri, 26 Mar 2010 16:58:49 +0100 (CET) Subject: [pypy-svn] r72909 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100326155849.26354282B9C@codespeak.net> Author: xoraxax Date: Fri Mar 26 16:58:47 2010 New Revision: 72909 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py (contents, props changed) Removed: pypy/branch/cpython-extension/pypy/module/cpyext/include/typeobject.c Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Largish pile of changes, mainly to fix memory allocation/deallocation. * Rewrite PyType_Ready in Python. * Add a forgotten borrowing test. * DECREF all non-heaptypes at the end of the test run. * Break various dependency cycles by introducing a bootstrapping function. The hardest cycle is the dependency of pto creation on tuple objects for tp_bases. * Created debug_refcount function and added output of function names. * Reworked borrowing by adding a register_container function that needs to be called in functions that borrow. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Fri Mar 26 16:58:47 2010 @@ -8,6 +8,7 @@ from pypy.rpython.tool import rffi_platform from pypy.rpython.lltypesystem import ll2ctypes from pypy.rpython.annlowlevel import llhelper +from pypy.rlib.objectmodel import we_are_translated from pypy.translator.c.database import LowLevelDatabase from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.tool.udir import udir @@ -20,6 +21,8 @@ # CPython 2.4 compatibility from py.builtin import BaseException +DEBUG_REFCOUNT = True +DEBUG_WRAPPER = False Py_ssize_t = lltype.Signed ADDR = lltype.Signed @@ -144,6 +147,7 @@ func.api_func = api_function unwrapper.api_func = api_function unwrapper.func = func + unwrapper.__name__ = "uw(%s)" % (func.__name__, ) if external: FUNCTIONS[func.func_name] = api_function INTERPLEVEL_API[func.func_name] = unwrapper @@ -197,6 +201,7 @@ if name in TYPES: TYPES[name].become(TYPE) + class NullPointerException(Exception): pass @@ -217,8 +222,18 @@ hints["padding"] = hints["padding"] + tuple(pad_fields) return lltype.Struct(hints["c_name"], hints=hints, *new_fields) +def debug_refcount(*args, **kwargs): + frame_stackdepth = kwargs.pop("frame_stackdepth", 2) + assert not kwargs + if DEBUG_REFCOUNT: + frame = sys._getframe(frame_stackdepth) + print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), + for arg in args: + print >>sys.stderr, arg, + print >>sys.stderr + def make_ref(space, w_obj, borrowed=False, steal=False): - from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, DEBUG_REFCOUNT + from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF if w_obj is None: return lltype.nullptr(PyObject.TO) assert isinstance(w_obj, W_Root) @@ -230,12 +245,7 @@ w_type = space.type(w_obj) if space.is_w(w_type, space.w_type): py_obj = allocate_type_obj(space, w_obj) - py_obj.c_obj_refcnt = 1 - if space.is_w(w_type, w_obj): - pto = py_obj - Py_INCREF(space, pto) - else: - pto = make_ref(space, w_type) + # c_obj_type and c_obj_refcnt are set by allocate_type_obj elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) @@ -246,6 +256,7 @@ T = get_padded_type(PyObject.TO, basicsize) py_obj = lltype.malloc(T, None, flavor="raw") py_obj.c_obj_refcnt = 1 + py_obj.c_obj_type = rffi.cast(PyObject, pto) elif isinstance(w_obj, W_StringObject): py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw') py_obj.c_size = len(space.str_w(w_obj)) @@ -253,17 +264,18 @@ pto = make_ref(space, space.w_str) py_obj = rffi.cast(PyObject, py_obj) py_obj.c_obj_refcnt = 1 + py_obj.c_obj_type = rffi.cast(PyObject, pto) else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") py_obj.c_obj_refcnt = 1 pto = make_ref(space, space.type(w_obj)) - py_obj.c_obj_type = rffi.cast(PyObject, pto) + py_obj.c_obj_type = rffi.cast(PyObject, pto) + # XXX remove this weird casting? ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) py_obj = rffi.cast(PyObject, py_obj) - if DEBUG_REFCOUNT: - print >>sys.stderr, "MAKREF", py_obj, w_obj + debug_refcount("MAKREF", py_obj, w_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj if borrowed and ptr not in state.borrowed_objects: @@ -307,10 +319,20 @@ return obj - at cpython_api([PyObject, PyObject], lltype.Void, external=False) -def add_borrowed_object(space, container, obj): + at cpython_api([PyObject], lltype.Void, external=False) +def register_container(space, container): state = space.fromcache(State) container_ptr = rffi.cast(ADDR, container) + assert not state.last_container, "Last container was not fetched" + state.last_container = container_ptr + print "Setting last_container to", hex(container_ptr) + +def add_borrowed_object(space, obj): + state = space.fromcache(State) + container_ptr = state.last_container + state.last_container = 0 + if not container_ptr: + raise NullPointerException borrowees = state.borrow_mapping.get(container_ptr) if borrowees is None: state.borrow_mapping[container_ptr] = borrowees = {} @@ -327,7 +349,8 @@ def wrapper(*args): boxed_args = [] # XXX use unrolling_iterable here - print >>sys.stderr, callable, + if DEBUG_WRAPPER: + print >>sys.stderr, callable, for i, typ in enumerate(callable.api_func.argtypes): arg = args[i] if (typ is PyObject and @@ -340,7 +363,8 @@ state = space.fromcache(State) try: retval = callable(space, *boxed_args) - print >>sys.stderr, " DONE" + if DEBUG_WRAPPER: + print >>sys.stderr, " DONE" except OperationError, e: failed = True e.normalize_exception(space) @@ -363,13 +387,37 @@ return error_value if callable.api_func.restype is PyObject: - retval = make_ref(space, retval, borrowed=callable.api_func.borrowed) - if callable.api_func.restype is rffi.INT_real: + borrowed = callable.api_func.borrowed + retval = make_ref(space, retval, borrowed=borrowed) + if borrowed: + try: + add_borrowed_object(space, retval) + except NullPointerException, e: + if not we_are_translated(): + assert False, "Container not registered by %s" % (callable, ) + else: + raise + elif callable.api_func.restype is rffi.INT_real: retval = rffi.cast(rffi.INT_real, retval) return retval wrapper.__name__ = "wrapper for %r" % (callable, ) return wrapper +def bootstrap_types(space): + from pypy.module.cpyext.typeobject import PyTypeObjectPtr, PyPyType_Ready + # bootstrap this damn cycle + type_pto = make_ref(space, space.w_type) + type_pto = rffi.cast(PyTypeObjectPtr, type_pto) + object_pto = make_ref(space, space.w_object) + object_pto = rffi.cast(PyTypeObjectPtr, object_pto) + type_pto.c_tp_base = object_pto + type_pto.c_obj_type = make_ref(space, space.w_type) + object_pto.c_obj_type = make_ref(space, space.w_type) + PyPyType_Ready(space, object_pto, space.w_object) + PyPyType_Ready(space, type_pto, space.w_type) + type_pto.c_tp_bases = make_ref(space, space.newtuple([space.w_object])) + object_pto.c_tp_bases = make_ref(space, space.newtuple([])) + #_____________________________________________________ # Build the bridge DLL, Allow extension DLLs to call # back into Pypy space functions @@ -463,6 +511,7 @@ outputfilename=str(udir / "module_cache" / "pypyapi"), standalone=False) + bootstrap_types(space) # load the bridge, and init structure import ctypes bridge = ctypes.CDLL(str(modulename)) @@ -477,10 +526,6 @@ ptr = ctypes.c_void_p.in_dll(bridge, name) ptr.value = ctypes.cast(ll2ctypes.lltype2ctypes(make_ref(space, w_obj)), ctypes.c_void_p).value - # hack, init base of the type type - if name == "PyType_Type": - pto = rffi.cast(PyTypeObjectPtr, ptr) - pto.c_tp_base = make_ref(space, w_object) # implement structure initialization code for name, func in FUNCTIONS.iteritems(): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Fri Mar 26 16:58:47 2010 @@ -377,8 +377,6 @@ PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; -// defined in typeobject.c -int PyType_Ready(PyTypeObject *); /* objimpl.h ----------------------------------------------*/ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Fri Mar 26 16:58:47 2010 @@ -2,18 +2,16 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ - ADDR + ADDR, debug_refcount from pypy.module.cpyext.state import State -DEBUG_REFCOUNT = False # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, obj): from pypy.module.cpyext.typeobject import string_dealloc obj.c_obj_refcnt -= 1 - if DEBUG_REFCOUNT: - print >>sys.stderr, "DECREF", obj, obj.c_obj_refcnt + debug_refcount("DECREF", obj, obj.c_obj_refcnt, frame_stackdepth=3) if obj.c_obj_refcnt == 0: state = space.fromcache(State) ptr = rffi.cast(ADDR, obj) @@ -37,6 +35,10 @@ del state.borrowed_objects[containee_ptr] except KeyError: pass + else: + if DEBUG_REFCOUNT: + print >>sys.stderr, "Borrowed object is already gone:", \ + hex(containee) del state.borrow_mapping[ptr] else: assert obj.c_obj_refcnt > 0 @@ -44,8 +46,8 @@ @cpython_api([PyObject], lltype.Void) def Py_INCREF(space, obj): obj.c_obj_refcnt += 1 - if DEBUG_REFCOUNT: - print >>sys.stderr, "INCREF", obj, obj.c_obj_refcnt + assert obj.c_obj_refcnt > 0 + debug_refcount("INCREF", obj, obj.c_obj_refcnt, frame_stackdepth=3) @cpython_api([PyObject], lltype.Void) def Py_XDECREF(space, obj): @@ -55,7 +57,6 @@ def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr from pypy.module.cpyext.methodobject import generic_cpy_call - state = space.fromcache(State) pto = obj.c_obj_type pto = rffi.cast(PyTypeObjectPtr, pto) print >>sys.stderr, "Calling dealloc slot of", obj, \ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Fri Mar 26 16:58:47 2010 @@ -1,6 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL + METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL, \ + register_container from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall @@ -23,7 +24,7 @@ return w_mod @cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef), rffi.CCHARP, - PyObject, rffi.INT_real], PyObject, borrowed=True) + PyObject, rffi.INT_real], PyObject, borrowed=False) # we cannot borrow here def Py_InitModule4(space, name, methods, doc, w_self, apiver): modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) @@ -74,10 +75,12 @@ w_type = space.gettypeobject(Module.typedef) return general_check(space, w_obj, w_type) - at cpython_api([PyObject], PyObject) + at cpython_api([PyObject], PyObject, borrowed=True) def PyModule_GetDict(space, w_mod): if PyModule_Check(space, w_mod): assert isinstance(w_mod, Module) - return w_mod.getdict() + w_dict = w_mod.getdict() + register_container(space, w_mod) + return w_dict else: PyErr_BadInternalCall(space) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Fri Mar 26 16:58:47 2010 @@ -1,6 +1,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.lib.identity_dict import identity_dict from pypy.interpreter.error import OperationError +from pypy.rpython.lltypesystem import lltype class State: @@ -13,6 +14,8 @@ self.py_objects_r2w = {} # { addr of raw PyObject -> w_obj } self.borrow_mapping = {} # { addr of container -> { addr of containee -> None } } self.borrowed_objects = {} # { addr of containee -> None } + self.non_heaptypes = [] # list of wrapped objects + self.last_container = 0 # addr of last container self.exc_type = None self.exc_value = None Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py Fri Mar 26 16:58:47 2010 @@ -0,0 +1,43 @@ +import py +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.state import State +from pypy.module.cpyext.api import make_ref, add_borrowed_object + + +class TestBorrowing(BaseApiTest): + def test_borrowing(self, space, api): + state = space.fromcache(State) + w_int = space.wrap(1) + w_tuple = space.newtuple([w_int]) + api.Py_INCREF(w_tuple) + api.register_container(w_tuple) + one_pyo = make_ref(space, w_int, borrowed=True) + add_borrowed_object(space, one_pyo) + print state.borrowed_objects + api.Py_DECREF(w_tuple) + state.print_refcounts() + py.test.raises(AssertionError, api.Py_DECREF, one_pyo) + +class AppTestStringObject(AppTestCpythonExtensionBase): + def test_tuple_borrowing(self): + module = self.import_extension('foo', [ + ("test_borrowing", "METH_NOARGS", + """ + PyObject *t = PyTuple_New(1); + PyObject *f = PyFloat_FromDouble(42.0); + PyObject *g = NULL; + printf("Refcnt1: %i\\n", Py_REFCNT(f)); + PyTuple_SetItem(t, 0, f); // steals reference + printf("Refcnt2: %i\\n", Py_REFCNT(f)); + f = PyTuple_GetItem(t, 0); // borrows reference + printf("Refcnt3: %i\\n", Py_REFCNT(f)); + g = PyTuple_GetItem(t, 0); // borrows reference again + printf("Refcnt4: %i\\n", Py_REFCNT(f)); + printf("COMPARE: %i\\n", f == g); + Py_DECREF(t); + Py_RETURN_TRUE; + """), + ]) + assert module.test_borrowing() # the test should not leak + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Fri Mar 26 16:58:47 2010 @@ -118,7 +118,7 @@ self.w_import_module = self.space.wrap(self.import_module) self.w_import_extension = self.space.wrap(self.import_extension) self.freeze_refcnts() - #self.check_and_print_leaks("Object %r leaked some time ago (refcount %i) -- Not executing test!") + #self.check_and_print_leaks() def teardown_method(self, func): try: @@ -127,6 +127,9 @@ self.space.delitem(self.space.sys.get('modules'), self.space.wrap('foo')) Py_DECREF(self.space, w_mod) + state = self.space.fromcache(State) + for w_obj in state.non_heaptypes: + Py_DECREF(self.space, w_obj) except OperationError: pass state = self.space.fromcache(State) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Fri Mar 26 16:58:47 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \ - general_check, CANNOT_FAIL, add_borrowed_object + general_check, CANNOT_FAIL, register_container from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.tupleobject import W_TupleObject @@ -29,5 +29,5 @@ PyErr_BadInternalCall(space) assert isinstance(w_t, W_TupleObject) w_obj = w_t.wrappeditems[pos] - add_borrowed_object(space, w_t, w_obj) + register_container(space, w_t) return w_obj Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Fri Mar 26 16:58:47 2010 @@ -12,12 +12,12 @@ from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ - PyStringObject, ADDR + PyStringObject, ADDR, from_ref from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs from pypy.module.cpyext.state import State from pypy.module.cpyext.methodobject import generic_cpy_call -from pypy.module.cpyext.macros import Py_DECREF, Py_XDECREF +from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, Py_XDECREF PyTypeObject = lltype.ForwardReference() PyTypeObjectPtr = lltype.Ptr(PyTypeObject) @@ -250,25 +250,37 @@ @cpython_api([PyObject], lltype.Void, external=False) def type_dealloc(space, obj): + state = space.fromcache(State) obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) Py_XDECREF(space, base_pyo) - # XXX XDECREF tp_dict, tp_bases, tp_mro, tp_cache, + Py_XDECREF(space, obj_pto.c_tp_bases) + # XXX XDECREF tp_dict, tp_mro, tp_cache, # tp_subclasses # free tp_doc - lltype.free(obj_pto.c_tp_name, flavor="raw") - obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) - generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) - pto = rffi.cast(PyObject, type_pto) - Py_DECREF(space, pto) + if obj_pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: + lltype.free(obj_pto.c_tp_name, flavor="raw") + obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) + generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) + pto = rffi.cast(PyObject, type_pto) + Py_DECREF(space, pto) + def allocate_type_obj(space, w_type): """ Allocates a pto from a w_type which must be a PyPy type. """ + state = space.fromcache(State) from pypy.module.cpyext.object import PyObject_dealloc, PyObject_Del assert not isinstance(w_type, W_PyCTypeObject) assert isinstance(w_type, W_TypeObject) + pto = lltype.malloc(PyTypeObject, None, flavor="raw") + pto.c_obj_refcnt = 1 + # put the type object early into the dict + # to support dependency cycles like object/type + state = space.fromcache(State) + state.py_objects_w2r[w_type] = rffi.cast(PyObject, pto) + if space.is_w(w_type, space.w_object): pto.c_tp_dealloc = PyObject_dealloc.api_func.get_llhelper(space) elif space.is_w(w_type, space.w_type): @@ -284,25 +296,64 @@ bases_w = w_type.bases_w assert len(bases_w) <= 1 pto.c_tp_base = lltype.nullptr(PyTypeObject) - if bases_w and not space.is_w(w_type, space.w_type): # avoid endless recursion - ref = make_ref(space, bases_w[0]) - pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref) + pto.c_tp_bases = lltype.nullptr(PyObject.TO) + if not space.is_w(w_type, space.w_type) and not \ + space.is_w(w_type, space.w_object): + if bases_w: + ref = make_ref(space, bases_w[0]) + pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref) + pto.c_obj_type = make_ref(space, space.type(space.w_type)) + PyPyType_Ready(space, pto, w_type) + else: + pto.c_obj_type = lltype.nullptr(PyObject.TO) + # XXX fill slots in pto return pto - at cpython_api_c() + at cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1) def PyType_Ready(space, pto): - "Implemented in typeobject.c" + return PyPyType_Ready(space, pto, None) + +def PyPyType_Ready(space, pto, w_obj): + try: + pto.c_tp_dict = lltype.nullptr(PyObject.TO) # not supported + if pto.c_tp_flags & Py_TPFLAGS_READY: + return 0 + assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0 + pto.c_tp_flags |= Py_TPFLAGS_READYING + base = pto.c_tp_base + if not base and not (w_obj is not None and + space.is_w(w_obj, space.w_object)): + base_pyo = make_ref(space, space.w_object) + base = pto.c_tp_base = rffi.cast(PyTypeObjectPtr, base_pyo) + if base and not base.c_tp_flags & Py_TPFLAGS_READY: + PyPyType_Ready(space, base, None) + if base and not pto.c_obj_type: # will be filled later + pto.c_obj_type = base.c_obj_type + if not pto.c_tp_bases and not (space.is_w(w_obj, space.w_object) + or space.is_w(w_obj, space.w_type)): + if not base: + bases = space.newtuple([]) + else: + bases = space.newtuple([from_ref(space, base)]) + pto.c_tp_bases = make_ref(space, bases) + if w_obj is None: + PyPyType_Register(space, pto) + finally: + pto.c_tp_flags &= ~Py_TPFLAGS_READYING + pto.c_tp_flags = (pto.c_tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY + return 0 - at cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1) def PyPyType_Register(space, pto): state = space.fromcache(State) ptr = rffi.cast(ADDR, pto) if ptr not in state.py_objects_r2w: w_obj = space.allocate_instance(W_PyCTypeObject, space.gettypeobject(W_PyCTypeObject.typedef)) + state.non_heaptypes.append(w_obj) + pyo = rffi.cast(PyObject, pto) state.py_objects_r2w[ptr] = w_obj - state.py_objects_w2r[w_obj] = pto + state.py_objects_w2r[w_obj] = pyo w_obj.__init__(space, pto) w_obj.ready() return 1 From lucian at codespeak.net Fri Mar 26 17:25:37 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Fri, 26 Mar 2010 17:25:37 +0100 (CET) Subject: [pypy-svn] r72911 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100326162537.A6720282B9C@codespeak.net> Author: lucian Date: Fri Mar 26 17:25:36 2010 New Revision: 72911 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Remove typeobject.c fromt the list of files to be compiled. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Fri Mar 26 17:25:36 2010 @@ -501,8 +501,7 @@ eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], - separate_module_files=[include_dir / "typeobject.c", - include_dir / "varargwrapper.c"], + separate_module_files=[include_dir / "varargwrapper.c"], export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() From arigo at codespeak.net Fri Mar 26 19:01:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 19:01:50 +0100 (CET) Subject: [pypy-svn] r72918 - pypy/trunk/pypy/translator/c/src Message-ID: <20100326180150.C3BC4282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 19:01:49 2010 New Revision: 72918 Added: pypy/trunk/pypy/translator/c/src/winstuff.c (contents, props changed) Modified: pypy/trunk/pypy/translator/c/src/main.h Log: Copy Windows-specific stuff from CPython, namely, return EINVAL in function calls with invalid arguments instead of showing a dialog box (aaaaaargh). Modified: pypy/trunk/pypy/translator/c/src/main.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/main.h (original) +++ pypy/trunk/pypy/translator/c/src/main.h Fri Mar 26 19:01:49 2010 @@ -15,6 +15,10 @@ #ifndef PYPY_NOT_MAIN_FILE +#ifdef MS_WINDOWS +#include "src/winstuff.c" +#endif + int main(int argc, char *argv[]) { char *errmsg; @@ -29,6 +33,10 @@ goto error; } +#ifdef MS_WINDOWS + pypy_Windows_startup(); +#endif + errmsg = RPython_StartupCode(); if (errmsg) goto error; Added: pypy/trunk/pypy/translator/c/src/winstuff.c ============================================================================== --- (empty file) +++ pypy/trunk/pypy/translator/c/src/winstuff.c Fri Mar 26 19:01:49 2010 @@ -0,0 +1,37 @@ + +/************************************************************/ + /***** Windows-specific stuff. *****/ + + +/* copied from CPython. */ + +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) +/* crt variable checking in VisualStudio .NET 2005 */ +#include + +/* Invalid parameter handler. Sets a ValueError exception */ +static void +InvalidParameterHandler( + const wchar_t * expression, + const wchar_t * function, + const wchar_t * file, + unsigned int line, + uintptr_t pReserved) +{ + /* Do nothing, allow execution to continue. Usually this + * means that the CRT will set errno to EINVAL + */ +} +#endif + + +void pypy_Windows_startup(void) +{ +#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) + /* Set CRT argument error handler */ + _set_invalid_parameter_handler(InvalidParameterHandler); + /* turn off assertions within CRT in debug mode; + instead just return EINVAL */ + _CrtSetReportMode(_CRT_ASSERT, 0); +#endif +} From arigo at codespeak.net Fri Mar 26 19:03:40 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 19:03:40 +0100 (CET) Subject: [pypy-svn] r72919 - pypy/branch/fix-win/pypy/module/zipimport Message-ID: <20100326180340.0D555282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 19:03:38 2010 New Revision: 72919 Modified: pypy/branch/fix-win/pypy/module/zipimport/interp_zipimport.py Log: Fix. Modified: pypy/branch/fix-win/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/branch/fix-win/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/branch/fix-win/pypy/module/zipimport/interp_zipimport.py Fri Mar 26 19:03:38 2010 @@ -131,7 +131,7 @@ def _find_relative_path(self, filename): if filename.startswith(self.filename): filename = filename[len(self.filename):] - if filename.startswith(os.sep): + if filename.startswith(os.path.sep) or filename.startswith(ZIPSEP): filename = filename[1:] if ZIPSEP != os.path.sep: filename = filename.replace(os.path.sep, ZIPSEP) @@ -361,7 +361,7 @@ "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] - if prefix.startswith(os.sep): + if prefix.startswith(os.path.sep) or prefix.startswith(ZIPSEP): prefix = prefix[1:] w_result = space.wrap(W_ZipImporter(space, name, filename, zip_file.NameToInfo, prefix)) From arigo at codespeak.net Fri Mar 26 19:04:36 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 19:04:36 +0100 (CET) Subject: [pypy-svn] r72920 - pypy/branch/fix-win/pypy/module/posix/test Message-ID: <20100326180436.ADF14282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 19:04:35 2010 New Revision: 72920 Modified: pypy/branch/fix-win/pypy/module/posix/test/test_posix2.py Log: Slight increase of clarity. Modified: pypy/branch/fix-win/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/branch/fix-win/pypy/module/posix/test/test_posix2.py (original) +++ pypy/branch/fix-win/pypy/module/posix/test/test_posix2.py Fri Mar 26 19:04:35 2010 @@ -309,7 +309,8 @@ os = self.posix for i in range(5): stream = os.popen('echo 1') - assert stream.read() == '1\n' + res = stream.read() + assert res == '1\n' stream.close() if hasattr(__import__(os.name), '_getfullpathname'): From arigo at codespeak.net Fri Mar 26 19:07:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Mar 2010 19:07:09 +0100 (CET) Subject: [pypy-svn] r72921 - pypy/branch/fix-win/pypy/translator/c/src Message-ID: <20100326180709.BDF6F282B9C@codespeak.net> Author: arigo Date: Fri Mar 26 19:07:08 2010 New Revision: 72921 Added: pypy/branch/fix-win/pypy/translator/c/src/winstuff.c - copied unchanged from r72918, pypy/trunk/pypy/translator/c/src/winstuff.c Modified: pypy/branch/fix-win/pypy/translator/c/src/main.h Log: Merge r72918 from trunk. Modified: pypy/branch/fix-win/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/fix-win/pypy/translator/c/src/main.h (original) +++ pypy/branch/fix-win/pypy/translator/c/src/main.h Fri Mar 26 19:07:08 2010 @@ -15,6 +15,10 @@ #ifndef PYPY_NOT_MAIN_FILE +#ifdef MS_WINDOWS +#include "src/winstuff.c" +#endif + int main(int argc, char *argv[]) { char *errmsg; @@ -29,6 +33,10 @@ goto error; } +#ifdef MS_WINDOWS + pypy_Windows_startup(); +#endif + errmsg = RPython_StartupCode(); if (errmsg) goto error; From benjamin at codespeak.net Fri Mar 26 19:22:23 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Fri, 26 Mar 2010 19:22:23 +0100 (CET) Subject: [pypy-svn] r72922 - pypy/trunk/pypy/jit/backend/x86 Message-ID: <20100326182223.CC8F9282B9C@codespeak.net> Author: benjamin Date: Fri Mar 26 19:22:22 2010 New Revision: 72922 Modified: pypy/trunk/pypy/jit/backend/x86/runner.py Log: remove unused imports Modified: pypy/trunk/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/runner.py (original) +++ pypy/trunk/pypy/jit/backend/x86/runner.py Fri Mar 26 19:22:22 2010 @@ -1,6 +1,3 @@ -import sys -import ctypes -import py from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.objectmodel import we_are_translated From getxsick at codespeak.net Fri Mar 26 19:32:22 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 26 Mar 2010 19:32:22 +0100 (CET) Subject: [pypy-svn] r72923 - pypy/build/ubuntu/1.2.0/debian Message-ID: <20100326183222.25EAE282B9C@codespeak.net> Author: getxsick Date: Fri Mar 26 19:32:20 2010 New Revision: 72923 Modified: pypy/build/ubuntu/1.2.0/debian/changelog pypy/build/ubuntu/1.2.0/debian/control Log: add missing libexpat to build-depends Modified: pypy/build/ubuntu/1.2.0/debian/changelog ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/changelog (original) +++ pypy/build/ubuntu/1.2.0/debian/changelog Fri Mar 26 19:32:20 2010 @@ -1,3 +1,10 @@ +pypy (1.2.0-4) karmic; urgency=low + + * Add missing build-depends. + * Update distribution to karmic. + + -- Bartosz Skowron Fri, 26 Mar 2010 12:40:31 +0100 + pypy (1.2.0-3) jaunty; urgency=low * New upstream release. Modified: pypy/build/ubuntu/1.2.0/debian/control ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/control (original) +++ pypy/build/ubuntu/1.2.0/debian/control Fri Mar 26 19:32:20 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev Standards-Version: 3.8.0 Homepage: http://pypy.org From getxsick at codespeak.net Fri Mar 26 21:31:10 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 26 Mar 2010 21:31:10 +0100 (CET) Subject: [pypy-svn] r72929 - pypy/trunk/lib-python Message-ID: <20100326203110.CE74E282BF5@codespeak.net> Author: getxsick Date: Fri Mar 26 21:31:06 2010 New Revision: 72929 Modified: pypy/trunk/lib-python/conftest.py Log: add _rawffi module for test_sqlite Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Fri Mar 26 21:31:06 2010 @@ -479,7 +479,7 @@ RegrTest('test_pep352.py'), RegrTest('test_platform.py'), RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread"), + RegrTest('test_sqlite.py', usemodules="thread _rawffi"), RegrTest('test_startfile.py', skip="bogus test"), RegrTest('test_structmembers.py', skip="depends on _testcapi"), RegrTest('test_urllib2_localnet.py', usemodules="thread"), From getxsick at codespeak.net Fri Mar 26 21:43:48 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 26 Mar 2010 21:43:48 +0100 (CET) Subject: [pypy-svn] r72930 - pypy/trunk/lib-python Message-ID: <20100326204348.C4983282B9C@codespeak.net> Author: getxsick Date: Fri Mar 26 21:43:47 2010 New Revision: 72930 Modified: pypy/trunk/lib-python/conftest.py Log: test_sqlite requires zlib module as well Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Fri Mar 26 21:43:47 2010 @@ -479,7 +479,7 @@ RegrTest('test_pep352.py'), RegrTest('test_platform.py'), RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread _rawffi"), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_startfile.py', skip="bogus test"), RegrTest('test_structmembers.py', skip="depends on _testcapi"), RegrTest('test_urllib2_localnet.py', usemodules="thread"), From getxsick at codespeak.net Fri Mar 26 22:21:03 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Fri, 26 Mar 2010 22:21:03 +0100 (CET) Subject: [pypy-svn] r72931 - pypy/build/ubuntu/trunk/debian Message-ID: <20100326212103.E0433282B9C@codespeak.net> Author: getxsick Date: Fri Mar 26 22:21:02 2010 New Revision: 72931 Modified: pypy/build/ubuntu/trunk/debian/control Log: yet another missing depends Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Fri Mar 26 22:21:02 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libsqlite3-dev, libdb4.6 Standards-Version: 3.8.0 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.6 Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. From xoraxax at codespeak.net Sat Mar 27 00:38:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 00:38:49 +0100 (CET) Subject: [pypy-svn] r72932 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100326233849.9CF4F282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 00:38:47 2010 New Revision: 72932 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Disable refcount debugging. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 00:38:47 2010 @@ -21,7 +21,7 @@ # CPython 2.4 compatibility from py.builtin import BaseException -DEBUG_REFCOUNT = True +DEBUG_REFCOUNT = False DEBUG_WRAPPER = False Py_ssize_t = lltype.Signed From xoraxax at codespeak.net Sat Mar 27 00:41:02 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 00:41:02 +0100 (CET) Subject: [pypy-svn] r72933 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100326234102.5E5FA282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 00:41:00 2010 New Revision: 72933 Added: pypy/branch/cpython-extension/pypy/module/cpyext/Doc_stubgen_enable.patch pypy/branch/cpython-extension/pypy/module/cpyext/stubgen.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (contents, props changed) Log: Added a cpython_api stub generator and generated stubs from current CPython trunk. The stub generator works as follows: 1. Go to Doc (in your CPython checkout). 1. Run make text and stop it after it downloaded the prerequisites. 1. Apply the patch Doc_stubgen_enable.patch in your CPython checkout 1. Run make text again with PyPy in your Python path. 1. Voila, the stubs.py file will be updated. Added: pypy/branch/cpython-extension/pypy/module/cpyext/Doc_stubgen_enable.patch ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/Doc_stubgen_enable.patch Sat Mar 27 00:41:00 2010 @@ -0,0 +1,27 @@ +Index: Doc/tools/sphinx/ext/refcounting.py +=================================================================== +--- Doc/tools/sphinx/ext/refcounting.py (Revision 79453) ++++ Doc/tools/sphinx/ext/refcounting.py (Arbeitskopie) +@@ -91,6 +91,7 @@ + if app.config.refcount_file: + refcounts = Refcounts.fromfile( + path.join(app.srcdir, app.config.refcount_file)) ++ app._refcounts = refcounts + app.connect('doctree-read', refcounts.add_refcount_annotations) + + +Index: Doc/conf.py +=================================================================== +--- Doc/conf.py (Revision 79421) ++++ Doc/conf.py (Arbeitskopie) +@@ -13,8 +13,8 @@ + # General configuration + # --------------------- + +-extensions = ['sphinx.ext.refcounting', 'sphinx.ext.coverage', +- 'sphinx.ext.doctest', 'pyspecific'] ++extensions = ['pypy.module.cpyext.stubgen', 'sphinx.ext.refcounting', 'sphinx.ext.coverage', ++ 'sphinx.ext.doctest', 'pyspecific', ] + templates_path = ['tools/sphinxext'] + + # General substitutions. Added: pypy/branch/cpython-extension/pypy/module/cpyext/stubgen.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubgen.py Sat Mar 27 00:41:00 2010 @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +from os import path + +from pypy.module.cpyext import api + +from sphinx import addnodes + + +TEMPLATE = """ + at cpython_api([%(paramtypes)s], %(rettype)s%(borrows)s) +def %(functionname)s(%(params)s): +%(docstring)s raise NotImplementedError +""" + +C_TYPE_TO_PYPY_TYPE = { + "void": "lltype.Void", + "int": "rffi.INT_real", + "PyTypeObject*": "PyTypeObjectPtr", + "PyVarObject*": "PyObject", + "const char*": "rffi.CCHARP", + "PyObject*": "PyObject", + "char*": "rffi.CCHARP", + "PyMethodDef*": "PyMethodDef", + "Py_ssize_t": "Py_ssize_t", + "Py_ssize_t*": "Py_ssize_t", + "...": "...", + "char": "lltype.Char", + } + +C_TYPE_TO_PYPY_TYPE_ARGS = C_TYPE_TO_PYPY_TYPE.copy() +C_TYPE_TO_PYPY_TYPE_ARGS.update({ + "void": "rffi.VOIDP_real", + }) + + +def c_param_to_type_and_name(string, is_arg=True): + string = string.replace(" **", "** ").replace(" *", "* ") + try: + typ, name = string.rsplit(" ", 1) + except ValueError: + typ = string + name = "" + return [C_TYPE_TO_PYPY_TYPE, C_TYPE_TO_PYPY_TYPE_ARGS][is_arg]\ + .get(typ, "{" + typ + "}"), name + + +def process_doctree(app, doctree): + for node in doctree.traverse(addnodes.desc_content): + par = node.parent + if par['desctype'] != 'cfunction': + continue + if not par[0].has_key('names') or not par[0]['names']: + continue + functionname = par[0]['names'][0] + if api.FUNCTIONS.get(functionname) is not None: + print "Wow, you implemented already", functionname + continue + borrows = docstring = "" + crettype, _, cparameters = par[0] + crettype = crettype.astext() + cparameters = cparameters.astext() + rettype, _ = c_param_to_type_and_name(crettype, False) + params = ["space"] + paramtypes = [] + for param in cparameters.split(","): + typ, name = c_param_to_type_and_name(param.strip()) + params.append(name) + paramtypes.append(typ) + params = ", ".join(params) + paramtypes = ", ".join(paramtypes) + docstring = node.astext() + entry = app._refcounts.get(functionname) + if entry and entry.result_type in ("PyObject*", "PyVarObject*"): + if entry.result_refs is None: + docstring += "\nReturn value: always NULL." + else: + borrows = (", borrowed=True", "")[entry.result_refs] + docstring = "\n ".join(docstring.splitlines()) + if docstring: + docstring = ' """%s"""\n' % (docstring,) + code = TEMPLATE % locals() + app._stubgen_f.write(code) + + +def init_apidump(app): + fname = path.join(path.dirname(api.__file__), "stubs.py") + app._stubgen_f = file(fname, "w") + app.connect('doctree-read', process_doctree) + + +def setup(app): + app.connect('builder-inited', init_apidump) Added: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sat Mar 27 00:41:00 2010 @@ -0,0 +1,6971 @@ + + at cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject) +def _PyObject_NewVar(space, type, size): + """This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def _PyObject_Del(space, op): + raise NotImplementedError + + at cpython_api([PyObject, PyTypeObjectPtr], PyObject, borrowed=True) +def PyObject_Init(space, op, type): + """Initialize a newly-allocated object op with its type and initial + reference. Returns the initialized object. If type indicates that the + object participates in the cyclic garbage detector, it is added to the + detector's set of observed objects. Other fields of the object are not + affected.""" + raise NotImplementedError + + at cpython_api([PyObject, PyTypeObjectPtr, Py_ssize_t], PyObject, borrowed=True) +def PyObject_InitVar(space, op, type, size): + """This does everything PyObject_Init() does, and also initializes the + length information for a variable-size object. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{TYPE}, PyTypeObjectPtr], {TYPE*}) +def PyObject_New(space, , type): + """Allocate a new Python object using the C structure type TYPE and the + Python type object type. Fields not defined by the Python object header + are not initialized; the object's reference count will be one. The size of + the memory allocation is determined from the tp_basicsize field of + the type object.""" + raise NotImplementedError + + at cpython_api([{TYPE}, PyTypeObjectPtr, Py_ssize_t], {TYPE*}) +def PyObject_NewVar(space, , type, size): + """Allocate a new Python object using the C structure type TYPE and the + Python type object type. Fields not defined by the Python object header + are not initialized. The allocated memory allows for the TYPE structure + plus size fields of the size given by the tp_itemsize field of + type. This is useful for implementing objects like tuples, which are + able to determine their size at construction time. Embedding the array of + fields into the same allocation decreases the number of allocations, + improving the memory management efficiency. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyMethodDef], PyObject, borrowed=True) +def Py_InitModule(space, name, methods): + """Create a new module object based on a name and table of functions, + returning the new module object. + + Older versions of Python did not support NULL as the value for the + methods argument.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyMethodDef, rffi.CCHARP], PyObject, borrowed=True) +def Py_InitModule3(space, name, methods, doc): + """Create a new module object based on a name and table of functions, + returning the new module object. If doc is non-NULL, it will be used + to define the docstring for the module. + + Older versions of Python did not support NULL as the value for the + methods argument.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, ...], rffi.INT_real) +def PyArg_ParseTuple(space, args, format, ): + """Parse the parameters of a function that takes only positional parameters + into local variables. Returns true on success; on failure, it returns + false and raises the appropriate exception.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, {va_list}], rffi.INT_real) +def PyArg_VaParse(space, args, format, vargs): + """Identical to PyArg_ParseTuple(), except that it accepts a va_list + rather than a variable number of arguments.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.CCHARP, rffi.CCHARP, ...], rffi.INT_real) +def PyArg_ParseTupleAndKeywords(space, args, kw, format, keywords[], ): + """Parse the parameters of a function that takes both positional and keyword + parameters into local variables. Returns true on success; on failure, it + returns false and raises the appropriate exception.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.CCHARP, rffi.CCHARP, {va_list}], rffi.INT_real) +def PyArg_VaParseTupleAndKeywords(space, args, kw, format, keywords[], vargs): + """Identical to PyArg_ParseTupleAndKeywords(), except that it accepts a + va_list rather than a variable number of arguments.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, ...], rffi.INT_real) +def PyArg_Parse(space, args, format, ): + """Function used to deconstruct the argument lists of "old-style" functions + --- these are functions which use the METH_OLDARGS parameter + parsing method. This is not recommended for use in parameter parsing in + new code, and most code in the standard interpreter has been modified to no + longer use this for that purpose. It does remain a convenient way to + decompose other tuples, however, and may continue to be used for that + purpose.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, Py_ssize_t, Py_ssize_t, ...], rffi.INT_real) +def PyArg_UnpackTuple(space, args, name, min, max, ): + """A simpler form of parameter retrieval which does not use a format string to + specify the types of the arguments. Functions which use this method to + retrieve their parameters should be declared as METH_VARARGS in + function or method tables. The tuple containing the actual parameters + should be passed as args; it must actually be a tuple. The length of the + tuple must be at least min and no more than max; min and max may be + equal. Additional arguments must be passed to the function, each of which + should be a pointer to a PyObject* variable; these will be filled + in with the values from args; they will contain borrowed references. The + variables which correspond to optional parameters not given by args will + not be filled in; these should be initialized by the caller. This function + returns true on success and false if args is not a tuple or contains the + wrong number of elements; an exception will be set if there was a failure. + + This is an example of the use of this function, taken from the sources for + the _weakref helper module for weak references: + + static PyObject * + weakref_ref(PyObject *self, PyObject *args) + { + PyObject *object; + PyObject *callback = NULL; + PyObject *result = NULL; + + if (PyArg_UnpackTuple(args, "ref", 1, 2, &object, &callback)) { + result = PyWeakref_NewRef(object, callback); + } + return result; + } + + The call to PyArg_UnpackTuple() in this example is entirely + equivalent to this call to PyArg_ParseTuple(): + + PyArg_ParseTuple(args, "O|O:ref", &object, &callback) + + + + This function used an int type for min and max. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, ...], PyObject) +def Py_BuildValue(space, format, ): + """Create a new value based on a format string similar to those accepted by + the PyArg_Parse*() family of functions and a sequence of values. + Returns the value or NULL in the case of an error; an exception will be + raised if NULL is returned. + + Py_BuildValue() does not always build a tuple. It builds a tuple + only if its format string contains two or more format units. If the format + string is empty, it returns None; if it contains exactly one format + unit, it returns whatever object is described by that format unit. To + force it to return a tuple of size 0 or one, parenthesize the format + string. + + When memory buffers are passed as parameters to supply data to build + objects, as for the s and s# formats, the required data is copied. + Buffers provided by the caller are never referenced by the objects created + by Py_BuildValue(). In other words, if your code invokes + malloc() and passes the allocated memory to Py_BuildValue(), + your code is responsible for calling free() for that memory once + Py_BuildValue() returns. + + In the following description, the quoted form is the format unit; the entry + in (round) parentheses is the Python object type that the format unit will + return; and the entry in [square] brackets is the type of the C value(s) to + be passed. + + The characters space, tab, colon and comma are ignored in format strings + (but not within format units such as s#). This can be used to make + long format strings a tad more readable. + + s (string) [char *] + + Convert a null-terminated C string to a Python object. If the C string + pointer is NULL, None is used. + + s# (string) [char *, int] + + Convert a C string and its length to a Python object. If the C string + pointer is NULL, the length is ignored and None is returned. + + z (string or None) [char *] + + Same as s. + + z# (string or None) [char *, int] + + Same as s#. + + u (Unicode string) [Py_UNICODE *] + + Convert a null-terminated buffer of Unicode (UCS-2 or UCS-4) data to a + Python Unicode object. If the Unicode buffer pointer is NULL, + None is returned. + + u# (Unicode string) [Py_UNICODE *, int] + + Convert a Unicode (UCS-2 or UCS-4) data buffer and its length to a + Python Unicode object. If the Unicode buffer pointer is NULL, the + length is ignored and None is returned. + + i (integer) [int] + + Convert a plain C int to a Python integer object. + + b (integer) [char] + + Convert a plain C char to a Python integer object. + + h (integer) [short int] + + Convert a plain C short int to a Python integer object. + + l (integer) [long int] + + Convert a C long int to a Python integer object. + + B (integer) [unsigned char] + + Convert a C unsigned char to a Python integer object. + + H (integer) [unsigned short int] + + Convert a C unsigned short int to a Python integer object. + + I (integer/long) [unsigned int] + + Convert a C unsigned int to a Python integer object or a Python + long integer object, if it is larger than sys.maxint. + + k (integer/long) [unsigned long] + + Convert a C unsigned long to a Python integer object or a + Python long integer object, if it is larger than sys.maxint. + + L (long) [PY_LONG_LONG] + + Convert a C long long to a Python long integer object. Only + available on platforms that support long long. + + K (long) [unsigned PY_LONG_LONG] + + Convert a C unsigned long long to a Python long integer object. + Only available on platforms that support unsigned long long. + + n (int) [Py_ssize_t] + + Convert a C Py_ssize_t to a Python integer or long integer. + + + + c (string of length 1) [char] + + Convert a C int representing a character to a Python string of + length 1. + + d (float) [double] + + Convert a C double to a Python floating point number. + + f (float) [float] + + Same as d. + + D (complex) [Py_complex *] + + Convert a C Py_complex structure to a Python complex number. + + O (object) [PyObject *] + + Pass a Python object untouched (except for its reference count, which is + incremented by one). If the object passed in is a NULL pointer, it is + assumed that this was caused because the call producing the argument + found an error and set an exception. Therefore, Py_BuildValue() + will return NULL but won't raise an exception. If no exception has + been raised yet, SystemError is set. + + S (object) [PyObject *] + + Same as O. + + N (object) [PyObject *] + + Same as O, except it doesn't increment the reference count on the + object. Useful when the object is created by a call to an object + constructor in the argument list. + + O& (object) [converter, anything] + + Convert anything to a Python object through a converter function. + The function is called with anything (which should be compatible with + void *) as its argument and should return a "new" Python + object, or NULL if an error occurred. + + (items) (tuple) [matching-items] + + Convert a sequence of C values to a Python tuple with the same number of + items. + + [items] (list) [matching-items] + + Convert a sequence of C values to a Python list with the same number of + items. + + {items} (dictionary) [matching-items] + + Convert a sequence of C values to a Python dictionary. Each pair of + consecutive C values adds one item to the dictionary, serving as key and + value, respectively. + + If there is an error in the format string, the SystemError exception + is set and NULL returned.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {va_list}], PyObject) +def Py_VaBuildValue(space, format, vargs): + """Identical to Py_BuildValue(), except that it accepts a va_list + rather than a variable number of arguments.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyObject_CheckBuffer(space, obj): + """Return 1 if obj supports the buffer interface otherwise 0.""" + raise NotImplementedError + + at cpython_api([PyObject, {Py_buffer*}, rffi.INT_real], rffi.INT_real) +def PyObject_GetBuffer(space, obj, view, flags): + """Export obj into a Py_buffer, view. These arguments must + never be NULL. The flags argument is a bit field indicating what + kind of buffer the caller is prepared to deal with and therefore what + kind of buffer the exporter is allowed to return. The buffer interface + allows for complicated memory sharing possibilities, but some caller may + not be able to handle all the complexity but may want to see if the + exporter will let them take a simpler view to its memory. + + Some exporters may not be able to share memory in every possible way and + may need to raise errors to signal to some consumers that something is + just not possible. These errors should be a BufferError unless + there is another error that is actually causing the problem. The + exporter can use flags information to simplify how much of the + Py_buffer structure is filled in with non-default values and/or + raise an error if the object can't support a simpler view of its memory. + + 0 is returned on success and -1 on error. + + The following table gives possible values to the flags arguments. + + + + + + Flag + + Description + + PyBUF_SIMPLE + + This is the default flag state. The returned + buffer may or may not have writable memory. The + format of the data will be assumed to be unsigned + bytes. This is a "stand-alone" flag constant. It + never needs to be '|'d to the others. The exporter + will raise an error if it cannot provide such a + contiguous buffer of bytes. + + PyBUF_WRITABLE + + The returned buffer must be writable. If it is + not writable, then raise an error. + + PyBUF_STRIDES + + This implies PyBUF_ND. The returned + buffer must provide strides information (i.e. the + strides cannot be NULL). This would be used when + the consumer can handle strided, discontiguous + arrays. Handling strides automatically assumes + you can handle shape. The exporter can raise an + error if a strided representation of the data is + not possible (i.e. without the suboffsets). + + PyBUF_ND + + The returned buffer must provide shape + information. The memory will be assumed C-style + contiguous (last dimension varies the + fastest). The exporter may raise an error if it + cannot provide this kind of contiguous buffer. If + this is not given then shape will be NULL. + + PyBUF_C_CONTIGUOUS + PyBUF_F_CONTIGUOUS + PyBUF_ANY_CONTIGUOUS + + These flags indicate that the contiguity returned + buffer must be respectively, C-contiguous (last + dimension varies the fastest), Fortran contiguous + (first dimension varies the fastest) or either + one. All of these flags imply + PyBUF_STRIDES and guarantee that the + strides buffer info structure will be filled in + correctly. + + PyBUF_INDIRECT + + This flag indicates the returned buffer must have + suboffsets information (which can be NULL if no + suboffsets are needed). This can be used when + the consumer can handle indirect array + referencing implied by these suboffsets. This + implies PyBUF_STRIDES. + + PyBUF_FORMAT + + The returned buffer must have true format + information if this flag is provided. This would + be used when the consumer is going to be checking + for what 'kind' of data is actually stored. An + exporter should always be able to provide this + information if requested. If format is not + explicitly requested then the format must be + returned as NULL (which means 'B', or + unsigned bytes) + + PyBUF_STRIDED + + This is equivalent to (PyBUF_STRIDES | + PyBUF_WRITABLE). + + PyBUF_STRIDED_RO + + This is equivalent to (PyBUF_STRIDES). + + PyBUF_RECORDS + + This is equivalent to (PyBUF_STRIDES | + PyBUF_FORMAT | PyBUF_WRITABLE). + + PyBUF_RECORDS_RO + + This is equivalent to (PyBUF_STRIDES | + PyBUF_FORMAT). + + PyBUF_FULL + + This is equivalent to (PyBUF_INDIRECT | + PyBUF_FORMAT | PyBUF_WRITABLE). + + PyBUF_FULL_RO + + This is equivalent to (PyBUF_INDIRECT | + PyBUF_FORMAT). + + PyBUF_CONTIG + + This is equivalent to (PyBUF_ND | + PyBUF_WRITABLE). + + PyBUF_CONTIG_RO + + This is equivalent to (PyBUF_ND).""" + raise NotImplementedError + + at cpython_api([{Py_buffer*}], lltype.Void) +def PyBuffer_Release(space, view): + """Release the buffer view. This should be called when the buffer + is no longer being used as it may free memory from it.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], Py_ssize_t) +def PyBuffer_SizeFromFormat(space, ): + """Return the implied ~Py_buffer.itemsize from the struct-stype + ~Py_buffer.format.""" + raise NotImplementedError + + at cpython_api([PyObject, {void*}, Py_ssize_t, lltype.Char], rffi.INT_real) +def PyObject_CopyToObject(space, obj, buf, len, fortran): + """Copy len bytes of data pointed to by the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. The buffer must of + course be writable. Return 0 on success and return -1 and raise an error + on failure. If the object does not have a writable buffer, then an error + is raised. If fortran is 'F', then if the object is + multi-dimensional, then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If fortran is + 'C', then the data will be copied into the array in C-style (last + dimension varies the fastest). If fortran is 'A', then it does not + matter and the copy will be made in whatever way is more efficient.""" + raise NotImplementedError + + at cpython_api([{Py_buffer*}, lltype.Char], rffi.INT_real) +def PyBuffer_IsContiguous(space, view, fortran): + """Return 1 if the memory defined by the view is C-style (fortran is + 'C') or Fortran-style (fortran is 'F') contiguous or either one + (fortran is 'A'). Return 0 otherwise.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, Py_ssize_t, Py_ssize_t, Py_ssize_t, lltype.Char], lltype.Void) +def PyBuffer_FillContiguousStrides(space, ndim, shape, strides, itemsize, fortran): + """Fill the strides array with byte-strides of a contiguous (C-style if + fortran is 'C' or Fortran-style if fortran is 'F' array of the + given shape with the given number of bytes per element.""" + raise NotImplementedError + + at cpython_api([{Py_buffer*}, PyObject, {void*}, Py_ssize_t, rffi.INT_real, rffi.INT_real], rffi.INT_real) +def PyBuffer_FillInfo(space, view, obj, buf, len, readonly, infoflags): + """Fill in a buffer-info structure, view, correctly for an exporter that can + only share a contiguous chunk of memory of "unsigned bytes" of the given + length. Return 0 on success and -1 (with raising an error) on error.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyMemoryView_FromObject(space, obj): + """Return a memoryview object from an object that defines the buffer interface.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyBuffer_Check(space, p): + """Return true if the argument has type PyBuffer_Type.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) +def PyBuffer_FromObject(space, base, offset, size): + """Return a new read-only buffer object. This raises TypeError if + base doesn't support the read-only buffer protocol or doesn't provide + exactly one buffer segment, or it raises ValueError if offset is + less than zero. The buffer will hold a reference to the base object, and + the buffer's contents will refer to the base object's buffer interface, + starting as position offset and extending for size bytes. If size is + Py_END_OF_BUFFER, then the new buffer's contents extend to the + length of the base object's exported buffer data. + + This function used an int type for offset and size. This + might require changes in your code for properly supporting 64-bit + systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) +def PyBuffer_FromReadWriteObject(space, base, offset, size): + """Return a new writable buffer object. Parameters and exceptions are similar + to those for PyBuffer_FromObject(). If the base object does not + export the writeable buffer protocol, then TypeError is raised. + + This function used an int type for offset and size. This + might require changes in your code for properly supporting 64-bit + systems.""" + raise NotImplementedError + + at cpython_api([{void*}, Py_ssize_t], PyObject) +def PyBuffer_FromMemory(space, ptr, size): + """Return a new read-only buffer object that reads from a specified location + in memory, with a specified size. The caller is responsible for ensuring + that the memory buffer, passed in as ptr, is not deallocated while the + returned buffer object exists. Raises ValueError if size is less + than zero. Note that Py_END_OF_BUFFER may not be passed for the + size parameter; ValueError will be raised in that case. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{void*}, Py_ssize_t], PyObject) +def PyBuffer_FromReadWriteMemory(space, ptr, size): + """Similar to PyBuffer_FromMemory(), but the returned buffer is + writable. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([Py_ssize_t], PyObject) +def PyBuffer_New(space, size): + """Return a new writable buffer object that maintains its own memory buffer of + size bytes. ValueError is returned if size is not zero or + positive. Note that the memory buffer (as returned by + PyObject_AsWriteBuffer()) is not specifically aligned. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyByteArray_Check(space, o): + """Return true if the object o is a bytearray object or an instance of a + subtype of the bytearray type.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyByteArray_CheckExact(space, o): + """Return true if the object o is a bytearray object, but not an instance of a + subtype of the bytearray type.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyByteArray_FromObject(space, o): + """Return a new bytearray object from any object, o, that implements the + buffer protocol. + + XXX expand about the buffer protocol, at least somewhere""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) +def PyByteArray_FromStringAndSize(space, string, len): + """Create a new bytearray object from string and its length, len. On + failure, NULL is returned.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyByteArray_Concat(space, a, b): + """Concat bytearrays a and b and return a new bytearray with the result.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyByteArray_Size(space, bytearray): + """Return the size of bytearray after checking for a NULL pointer.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyByteArray_AsString(space, bytearray): + """Return the contents of bytearray as a char array after checking for a + NULL pointer.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], rffi.INT_real) +def PyByteArray_Resize(space, bytearray, len): + """Resize the internal buffer of bytearray to len.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyByteArray_AS_STRING(space, bytearray): + """Macro version of PyByteArray_AsString().""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyByteArray_GET_SIZE(space, bytearray): + """Macro version of PyByteArray_Size().""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyCapsule_CheckExact(space, p): + """Return true if its argument is a PyCapsule.""" + raise NotImplementedError + + at cpython_api([{void*}, rffi.CCHARP, {PyCapsule_Destructor}], PyObject) +def PyCapsule_New(space, pointer, name, destructor): + """Create a PyCapsule encapsulating the pointer. The pointer + argument may not be NULL. + + On failure, set an exception and return NULL. + + The name string may either be NULL or a pointer to a valid C string. If + non-NULL, this string must outlive the capsule. (Though it is permitted to + free it inside the destructor.) + + If the destructor argument is not NULL, it will be called with the + capsule as its argument when it is destroyed. + + If this capsule will be stored as an attribute of a module, the name should + be specified as modulename.attributename. This will enable other modules + to import the capsule using PyCapsule_Import().""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], {void*}) +def PyCapsule_GetPointer(space, capsule, name): + """Retrieve the pointer stored in the capsule. On failure, set an exception + and return NULL. + + The name parameter must compare exactly to the name stored in the capsule. + If the name stored in the capsule is NULL, the name passed in must also + be NULL. Python uses the C function strcmp() to compare capsule + names.""" + raise NotImplementedError + + at cpython_api([PyObject], {PyCapsule_Destructor}) +def PyCapsule_GetDestructor(space, capsule): + """Return the current destructor stored in the capsule. On failure, set an + exception and return NULL. + + It is legal for a capsule to have a NULL destructor. This makes a NULL + return code somewhat ambiguous; use PyCapsule_IsValid() or + PyErr_Occurred() to disambiguate.""" + raise NotImplementedError + + at cpython_api([PyObject], {void*}) +def PyCapsule_GetContext(space, capsule): + """Return the current context stored in the capsule. On failure, set an + exception and return NULL. + + It is legal for a capsule to have a NULL context. This makes a NULL + return code somewhat ambiguous; use PyCapsule_IsValid() or + PyErr_Occurred() to disambiguate.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyCapsule_GetName(space, capsule): + """Return the current name stored in the capsule. On failure, set an exception + and return NULL. + + It is legal for a capsule to have a NULL name. This makes a NULL return + code somewhat ambiguous; use PyCapsule_IsValid() or + PyErr_Occurred() to disambiguate.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real], {void*}) +def PyCapsule_Import(space, name, no_block): + """Import a pointer to a C object from a capsule attribute in a module. The + name parameter should specify the full name to the attribute, as in + module.attribute. The name stored in the capsule must match this + string exactly. If no_block is true, import the module without blocking + (using PyImport_ImportModuleNoBlock()). If no_block is false, + import the module conventionally (using PyImport_ImportModule()). + + Return the capsule's internal pointer on success. On failure, set an + exception and return NULL. However, if PyCapsule_Import() failed to + import the module, and no_block was true, no exception is set.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyCapsule_IsValid(space, capsule, name): + """Determines whether or not capsule is a valid capsule. A valid capsule is + non-NULL, passes PyCapsule_CheckExact(), has a non-NULL pointer + stored in it, and its internal name matches the name parameter. (See + PyCapsule_GetPointer() for information on how capsule names are + compared.) + + In other words, if PyCapsule_IsValid() returns a true value, calls to + any of the accessors (any function starting with PyCapsule_Get()) are + guaranteed to succeed. + + Return a nonzero value if the object is valid and matches the name passed in. + Return 0 otherwise. This function will not fail.""" + raise NotImplementedError + + at cpython_api([PyObject, {void*}], rffi.INT_real) +def PyCapsule_SetContext(space, capsule, context): + """Set the context pointer inside capsule to context. + + Return 0 on success. Return nonzero and set an exception on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, {PyCapsule_Destructor}], rffi.INT_real) +def PyCapsule_SetDestructor(space, capsule, destructor): + """Set the destructor inside capsule to destructor. + + Return 0 on success. Return nonzero and set an exception on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyCapsule_SetName(space, capsule, name): + """Set the name inside capsule to name. If non-NULL, the name must + outlive the capsule. If the previous name stored in the capsule was not + NULL, no attempt is made to free it. + + Return 0 on success. Return nonzero and set an exception on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, {void*}], rffi.INT_real) +def PyCapsule_SetPointer(space, capsule, pointer): + """Set the void pointer inside capsule to pointer. The pointer may not be + NULL. + + Return 0 on success. Return nonzero and set an exception on failure.""" + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyCell_Check(space, ): + """Return true if ob is a cell object; ob must not be NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyCell_New(space, ob): + """Create and return a new cell object containing the value ob. The parameter may + be NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyCell_Get(space, cell): + """Return the contents of the cell cell.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyCell_GET(space, cell): + """Return the contents of the cell cell, but without checking that cell is + non-NULL and a cell object.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyCell_Set(space, cell, value): + """Set the contents of the cell object cell to value. This releases the + reference to any current content of the cell. value may be NULL. cell + must be non-NULL; if it is not a cell object, -1 will be returned. On + success, 0 will be returned.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], lltype.Void) +def PyCell_SET(space, cell, value): + """Sets the value of the cell object cell to value. No reference counts are + adjusted, and no checks are made for safety; cell must be non-NULL and must + be a cell object.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyClass_Check(space, o): + """Return true if the object o is a class object, including instances of types + derived from the standard class object. Return false in all other cases.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyClass_IsSubclass(space, klass, base): + """Return true if klass is a subclass of base. Return false in all other cases.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyInstance_Check(space, obj): + """Return true if obj is an instance.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PyInstance_New(space, class, arg, kw): + """Create a new instance of a specific class. The parameters arg and kw are + used as the positional and keyword parameters to the object's constructor.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyInstance_NewRaw(space, class, dict): + """Create a new instance of a specific class without calling its constructor. + class is the class of new object. The dict parameter will be used as the + object's __dict__; if NULL, a new dictionary will be created for the + instance.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyCObject_Check(space, p): + """Return true if its argument is a PyCObject.""" + raise NotImplementedError + + at cpython_api([{void*}, {void (*destr)(void*}], PyObject) +def PyCObject_FromVoidPtr(space, cobj, )): + """Create a PyCObject from the void * cobj. The destr function + will be called when the object is reclaimed, unless it is NULL.""" + raise NotImplementedError + + at cpython_api([{void*}, {void*}, {void (*destr)(void*}, {void*}], PyObject) +def PyCObject_FromVoidPtrAndDesc(space, cobj, desc, , )): + """Create a PyCObject from the void * cobj. The destr + function will be called when the object is reclaimed. The desc argument can + be used to pass extra callback data for the destructor function.""" + raise NotImplementedError + + at cpython_api([PyObject], {void*}) +def PyCObject_AsVoidPtr(space, self): + """Return the object void * that the PyCObject self was + created with.""" + raise NotImplementedError + + at cpython_api([PyObject], {void*}) +def PyCObject_GetDesc(space, self): + """Return the description void * that the PyCObject self was + created with.""" + raise NotImplementedError + + at cpython_api([PyObject, {void*}], rffi.INT_real) +def PyCObject_SetVoidPtr(space, self, cobj): + """Set the void pointer inside self to cobj. The PyCObject must not + have an associated destructor. Return true on success, false on failure.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyCode_Check(space, co): + """Return true if co is a code object""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyCode_GetNumFree(space, co): + """Return the number of free variables in co.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real, PyObject, PyObject, PyObject, PyObject, PyObject, PyObject, PyObject, PyObject, rffi.INT_real, PyObject], {PyCodeObject*}) +def PyCode_New(space, argcount, nlocals, stacksize, flags, code, consts, names, varnames, freevars, cellvars, filename, name, firstlineno, lnotab): + """Return a new code object. If you need a dummy code object to + create a frame, use PyCode_NewEmpty() instead. Calling + PyCode_New() directly can bind you to a precise Python + version since the definition of the bytecode changes often.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real], rffi.INT_real) +def PyCode_NewEmpty(space, filename, funcname, firstlineno): + """Return a new empty code object with the specified filename, + function name, and first line number. It is illegal to + exec or eval() the resulting code object.""" + raise NotImplementedError + + at cpython_api([{Py_complex}, {Py_complex}], {Py_complex}) +def _Py_c_sum(space, left, right): + """Return the sum of two complex numbers, using the C Py_complex + representation.""" + raise NotImplementedError + + at cpython_api([{Py_complex}, {Py_complex}], {Py_complex}) +def _Py_c_diff(space, left, right): + """Return the difference between two complex numbers, using the C + Py_complex representation.""" + raise NotImplementedError + + at cpython_api([{Py_complex}], {Py_complex}) +def _Py_c_neg(space, complex): + """Return the negation of the complex number complex, using the C + Py_complex representation.""" + raise NotImplementedError + + at cpython_api([{Py_complex}, {Py_complex}], {Py_complex}) +def _Py_c_prod(space, left, right): + """Return the product of two complex numbers, using the C Py_complex + representation.""" + raise NotImplementedError + + at cpython_api([{Py_complex}, {Py_complex}], {Py_complex}) +def _Py_c_quot(space, dividend, divisor): + """Return the quotient of two complex numbers, using the C Py_complex + representation.""" + raise NotImplementedError + + at cpython_api([{Py_complex}, {Py_complex}], {Py_complex}) +def _Py_c_pow(space, num, exp): + """Return the exponentiation of num by exp, using the C Py_complex + representation.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyComplex_Check(space, p): + """Return true if its argument is a PyComplexObject or a subtype of + PyComplexObject. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyComplex_CheckExact(space, p): + """Return true if its argument is a PyComplexObject, but not a subtype of + PyComplexObject. + """ + raise NotImplementedError + + at cpython_api([{Py_complex}], PyObject) +def PyComplex_FromCComplex(space, v): + """Create a new Python complex number object from a C Py_complex value.""" + raise NotImplementedError + + at cpython_api([{double}, {double}], PyObject) +def PyComplex_FromDoubles(space, real, imag): + """Return a new PyComplexObject object from real and imag.""" + raise NotImplementedError + + at cpython_api([PyObject], {double}) +def PyComplex_RealAsDouble(space, op): + """Return the real part of op as a C double.""" + raise NotImplementedError + + at cpython_api([PyObject], {double}) +def PyComplex_ImagAsDouble(space, op): + """Return the imaginary part of op as a C double.""" + raise NotImplementedError + + at cpython_api([PyObject], {Py_complex}) +def PyComplex_AsCComplex(space, op): + """Return the Py_complex value of the complex number op. + + If op is not a Python complex number object but has a __complex__() + method, this method will first be called to convert op to a Python complex + number object.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {size_t}, rffi.CCHARP, ...], rffi.INT_real) +def PyOS_snprintf(space, str, size, format, ): + """Output not more than size bytes to str according to the format string + format and the extra arguments. See the Unix man page snprintf(2).""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {size_t}, rffi.CCHARP, {va_list}], rffi.INT_real) +def PyOS_vsnprintf(space, str, size, format, va): + """Output not more than size bytes to str according to the format string + format and the variable argument list va. Unix man page + vsnprintf(2).""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {char**}, PyObject], {double}) +def PyOS_string_to_double(space, s, endptr, overflow_exception): + """Convert a string s to a double, raising a Python + exception on failure. The set of accepted strings corresponds to + the set of strings accepted by Python's float() constructor, + except that s must not have leading or trailing whitespace. + The conversion is independent of the current locale. + + If endptr is NULL, convert the whole string. Raise + ValueError and return -1.0 if the string is not a valid + representation of a floating-point number. + + If endptr is not NULL, convert as much of the string as + possible and set *endptr to point to the first unconverted + character. If no initial segment of the string is the valid + representation of a floating-point number, set *endptr to point + to the beginning of the string, raise ValueError, and return + -1.0. + + If s represents a value that is too large to store in a float + (for example, "1e500" is such a string on many platforms) then + if overflow_exception is NULL return Py_HUGE_VAL (with + an appropriate sign) and don't set any exception. Otherwise, + overflow_exception must point to a Python exception object; + raise that exception and return -1.0. In both cases, set + *endptr to point to the first character after the converted value. + + If any other error occurs during the conversion (for example an + out-of-memory error), set the appropriate Python exception and + return -1.0. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {char**}], {double}) +def PyOS_ascii_strtod(space, nptr, endptr): + """Convert a string to a double. This function behaves like the Standard C + function strtod() does in the C locale. It does this without changing the + current locale, since that would not be thread-safe. + + PyOS_ascii_strtod() should typically be used for reading configuration + files or other non-user input that should be locale independent. + + See the Unix man page strtod(2) for details. + + + + Use PyOS_string_to_double() instead.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {size_t}, rffi.CCHARP, {double}], rffi.CCHARP) +def PyOS_ascii_formatd(space, buffer, buf_len, format, d): + """Convert a double to a string using the '.' as the decimal + separator. format is a printf()-style format string specifying the + number format. Allowed conversion characters are 'e', 'E', 'f', + 'F', 'g' and 'G'. + + The return value is a pointer to buffer with the converted string or NULL if + the conversion failed. + + + + This function is removed in Python 2.7 and 3.1. Use PyOS_double_to_string() + instead.""" + raise NotImplementedError + + at cpython_api([{double}, lltype.Char, rffi.INT_real, rffi.INT_real, {int*}], rffi.CCHARP) +def PyOS_double_to_string(space, val, format_code, precision, flags, ptype): + """Convert a double val to a string using supplied + format_code, precision, and flags. + + format_code must be one of 'e', 'E', 'f', 'F', + 'g', 'G' or 'r'. For 'r', the supplied precision + must be 0 and is ignored. The 'r' format code specifies the + standard repr() format. + + flags can be zero or more of the values Py_DTSF_SIGN, + Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together: + + Py_DTSF_SIGN means to always precede the returned string with a sign + character, even if val is non-negative. + + Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look + like an integer. + + Py_DTSF_ALT means to apply "alternate" formatting rules. See the + documentation for the PyOS_snprintf() '#' specifier for + details. + + If ptype is non-NULL, then the value it points to will be set to one of + Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that + val is a finite number, an infinite number, or not a number, respectively. + + The return value is a pointer to buffer with the converted string or + NULL if the conversion failed. The caller is responsible for freeing the + returned string by calling PyMem_Free(). + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP], {double}) +def PyOS_ascii_atof(space, nptr): + """Convert a string to a double in a locale-independent way. + + See the Unix man page atof(2) for details. + + + + Use PyOS_string_to_double() instead.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP], rffi.CCHARP) +def PyOS_stricmp(space, s1, s2): + """Case insensitive comparison of strings. The function works almost + identically to strcmp() except that it ignores the case. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, {Py_ssize_t }], rffi.CCHARP) +def PyOS_strnicmp(space, s1, s2, size): + """Case insensitive comparison of strings. The function works almost + identically to strncmp() except that it ignores the case. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDate_Check(space, ob): + """Return true if ob is of type PyDateTime_DateType or a subtype of + PyDateTime_DateType. ob must not be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDate_CheckExact(space, ob): + """Return true if ob is of type PyDateTime_DateType. ob must not be + NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDateTime_Check(space, ob): + """Return true if ob is of type PyDateTime_DateTimeType or a subtype of + PyDateTime_DateTimeType. ob must not be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDateTime_CheckExact(space, ob): + """Return true if ob is of type PyDateTime_DateTimeType. ob must not + be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyTime_Check(space, ob): + """Return true if ob is of type PyDateTime_TimeType or a subtype of + PyDateTime_TimeType. ob must not be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyTime_CheckExact(space, ob): + """Return true if ob is of type PyDateTime_TimeType. ob must not be + NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDelta_Check(space, ob): + """Return true if ob is of type PyDateTime_DeltaType or a subtype of + PyDateTime_DeltaType. ob must not be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDelta_CheckExact(space, ob): + """Return true if ob is of type PyDateTime_DeltaType. ob must not be + NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyTZInfo_Check(space, ob): + """Return true if ob is of type PyDateTime_TZInfoType or a subtype of + PyDateTime_TZInfoType. ob must not be NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyTZInfo_CheckExact(space, ob): + """Return true if ob is of type PyDateTime_TZInfoType. ob must not be + NULL. + """ + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real], PyObject) +def PyDate_FromDate(space, year, month, day): + """Return a datetime.date object with the specified year, month and day. + """ + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real], PyObject) +def PyDateTime_FromDateAndTime(space, year, month, day, hour, minute, second, usecond): + """Return a datetime.datetime object with the specified year, month, day, hour, + minute, second and microsecond. + """ + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real, rffi.INT_real], PyObject) +def PyTime_FromTime(space, hour, minute, second, usecond): + """Return a datetime.time object with the specified hour, minute, second and + microsecond. + """ + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.INT_real, rffi.INT_real], PyObject) +def PyDelta_FromDSU(space, days, seconds, useconds): + """Return a datetime.timedelta object representing the given number of days, + seconds and microseconds. Normalization is performed so that the resulting + number of microseconds and seconds lie in the ranges documented for + datetime.timedelta objects. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Date*}], rffi.INT_real) +def PyDateTime_GET_YEAR(space, o): + """Return the year, as a positive int. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Date*}], rffi.INT_real) +def PyDateTime_GET_MONTH(space, o): + """Return the month, as an int from 1 through 12. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Date*}], rffi.INT_real) +def PyDateTime_GET_DAY(space, o): + """Return the day, as an int from 1 through 31. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_DateTime*}], rffi.INT_real) +def PyDateTime_DATE_GET_HOUR(space, o): + """Return the hour, as an int from 0 through 23. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_DateTime*}], rffi.INT_real) +def PyDateTime_DATE_GET_MINUTE(space, o): + """Return the minute, as an int from 0 through 59. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_DateTime*}], rffi.INT_real) +def PyDateTime_DATE_GET_SECOND(space, o): + """Return the second, as an int from 0 through 59. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_DateTime*}], rffi.INT_real) +def PyDateTime_DATE_GET_MICROSECOND(space, o): + """Return the microsecond, as an int from 0 through 999999. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Time*}], rffi.INT_real) +def PyDateTime_TIME_GET_HOUR(space, o): + """Return the hour, as an int from 0 through 23. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Time*}], rffi.INT_real) +def PyDateTime_TIME_GET_MINUTE(space, o): + """Return the minute, as an int from 0 through 59. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Time*}], rffi.INT_real) +def PyDateTime_TIME_GET_SECOND(space, o): + """Return the second, as an int from 0 through 59. + """ + raise NotImplementedError + + at cpython_api([{PyDateTime_Time*}], rffi.INT_real) +def PyDateTime_TIME_GET_MICROSECOND(space, o): + """Return the microsecond, as an int from 0 through 999999. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDateTime_FromTimestamp(space, args): + """Create and return a new datetime.datetime object given an argument tuple + suitable for passing to datetime.datetime.fromtimestamp(). + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDate_FromTimestamp(space, args): + """Create and return a new datetime.date object given an argument tuple + suitable for passing to datetime.date.fromtimestamp(). + """ + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, {struct PyGetSetDef*}], PyObject) +def PyDescr_NewGetSet(space, type, getset): + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, {struct PyMemberDef*}], PyObject) +def PyDescr_NewMember(space, type, meth): + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, {struct PyMethodDef*}], PyObject) +def PyDescr_NewMethod(space, type, meth): + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, {struct wrapperbase*}, {void*}], PyObject) +def PyDescr_NewWrapper(space, type, wrapper, wrapped): + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, PyMethodDef], PyObject) +def PyDescr_NewClassMethod(space, type, method): + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDescr_IsData(space, descr): + """Return true if the descriptor objects descr describes a data attribute, or + false if it describes a method. descr must be a descriptor object; there is + no error checking. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyWrapper_New(space, , ): + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyDict_CheckExact(space, p): + """Return true if p is a dict object, but not an instance of a subtype of + the dict type. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDictProxy_New(space, dict): + """Return a proxy object for a mapping which enforces read-only behavior. + This is normally used to create a proxy to prevent modification of the + dictionary for non-dynamic class types. + """ + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def PyDict_Clear(space, p): + """Empty an existing dictionary of all key-value pairs.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyDict_Contains(space, p, key): + """Determine if dictionary p contains key. If an item in p is matches + key, return 1, otherwise return 0. On error, return -1. + This is equivalent to the Python expression key in p. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDict_Copy(space, p): + """Return a new dictionary that contains the same key-value pairs as p. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real) +def PyDict_SetItem(space, p, key, val): + """Insert value into the dictionary p with a key of key. key must be + hashable; if it isn't, TypeError will be raised. Return + 0 on success or -1 on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyDict_DelItem(space, p, key): + """Remove the entry in dictionary p with key key. key must be hashable; + if it isn't, TypeError is raised. Return 0 on success or -1 + on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyDict_DelItemString(space, p, key): + """Remove the entry in dictionary p which has a key specified by the string + key. Return 0 on success or -1 on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject, borrowed=True) +def PyDict_GetItem(space, p, key): + """Return the object from dictionary p which has a key key. Return NULL + if the key key is not present, but without setting an exception.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], PyObject, borrowed=True) +def PyDict_GetItemString(space, p, key): + """This is the same as PyDict_GetItem(), but key is specified as a + char*, rather than a PyObject*.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDict_Items(space, p): + """Return a PyListObject containing all the items from the + dictionary, as in the dictionary method dict.items().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDict_Keys(space, p): + """Return a PyListObject containing all the keys from the dictionary, + as in the dictionary method dict.keys().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyDict_Values(space, p): + """Return a PyListObject containing all the values from the + dictionary p, as in the dictionary method dict.values().""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyDict_Size(space, p): + """ + + + + Return the number of items in the dictionary. This is equivalent to + len(p) on a dictionary. + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, {PyObject**}, {PyObject**}], rffi.INT_real) +def PyDict_Next(space, p, ppos, pkey, pvalue): + """Iterate over all key-value pairs in the dictionary p. The + Py_ssize_t referred to by ppos must be initialized to 0 + prior to the first call to this function to start the iteration; the + function returns true for each pair in the dictionary, and false once all + pairs have been reported. The parameters pkey and pvalue should either + point to PyObject* variables that will be filled in with each key + and value, respectively, or may be NULL. Any references returned through + them are borrowed. ppos should not be altered during iteration. Its + value represents offsets within the internal dictionary structure, and + since the structure is sparse, the offsets are not consecutive. + + For example: + + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(self->dict, &pos, &key, &value)) { + /* do something interesting with the values... */ + ... + } + + The dictionary p should not be mutated during iteration. It is safe + (since Python 2.1) to modify the values of the keys as you iterate over the + dictionary, but only so long as the set of keys does not change. For + example: + + PyObject *key, *value; + Py_ssize_t pos = 0; + + while (PyDict_Next(self->dict, &pos, &key, &value)) { + int i = PyInt_AS_LONG(value) + 1; + PyObject *o = PyInt_FromLong(i); + if (o == NULL) + return -1; + if (PyDict_SetItem(self->dict, key, o) < 0) { + Py_DECREF(o); + return -1; + } + Py_DECREF(o); + } + + This function used an int * type for ppos. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real) +def PyDict_Merge(space, a, b, override): + """Iterate over mapping object b adding key-value pairs to dictionary a. + b may be a dictionary, or any object supporting PyMapping_Keys() + and PyObject_GetItem(). If override is true, existing pairs in a + will be replaced if a matching key is found in b, otherwise pairs will + only be added if there is not a matching key in a. Return 0 on + success or -1 if an exception was raised. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyDict_Update(space, a, b): + """This is the same as PyDict_Merge(a, b, 1) in C, or a.update(b) in + Python. Return 0 on success or -1 if an exception was raised. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real) +def PyDict_MergeFromSeq2(space, a, seq2, override): + """Update or merge into dictionary a, from the key-value pairs in seq2. + seq2 must be an iterable object producing iterable objects of length 2, + viewed as key-value pairs. In case of duplicate keys, the last wins if + override is true, else the first wins. Return 0 on success or -1 + if an exception was raised. Equivalent Python (except for the return + value): + + def PyDict_MergeFromSeq2(a, seq2, override): + for key, value in seq2: + if override or key not in a: + a[key] = value + """ + raise NotImplementedError + + at cpython_api([rffi.INT_real], lltype.Void) +def PyErr_PrintEx(space, set_sys_last_vars): + """Print a standard traceback to sys.stderr and clear the error indicator. + Call this function only when the error indicator is set. (Otherwise it will + cause a fatal error!) + + If set_sys_last_vars is nonzero, the variables sys.last_type, + sys.last_value and sys.last_traceback will be set to the + type, value and traceback of the printed exception, respectively.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyErr_Print(space, ): + """Alias for PyErr_PrintEx(1).""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyErr_ExceptionMatches(space, exc): + """Equivalent to PyErr_GivenExceptionMatches(PyErr_Occurred(), exc). This + should only be called when an exception is actually set; a memory access + violation will occur if no exception has been raised.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyErr_GivenExceptionMatches(space, given, exc): + """Return true if the given exception matches the exception in exc. If + exc is a class object, this also returns true when given is an instance + of a subclass. If exc is a tuple, all exceptions in the tuple (and + recursively in subtuples) are searched for a match.""" + raise NotImplementedError + + at cpython_api([{PyObject**exc}, {PyObject**val}, {PyObject**tb}], lltype.Void) +def PyErr_NormalizeException(space, , , ): + """Under certain circumstances, the values returned by PyErr_Fetch() below + can be "unnormalized", meaning that *exc is a class object but *val is + not an instance of the same class. This function can be used to instantiate + the class in that case. If the values are already normalized, nothing happens. + The delayed normalization is implemented to improve performance.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, {PyObject**}, {PyObject**}], lltype.Void) +def PyErr_Fetch(space, ptype, pvalue, ptraceback): + """Retrieve the error indicator into three variables whose addresses are passed. + If the error indicator is not set, set all three variables to NULL. If it is + set, it will be cleared and you own a reference to each object retrieved. The + value and traceback object may be NULL even when the type object is not. + + This function is normally only used by code that needs to handle exceptions or + by code that needs to save and restore the error indicator temporarily.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], lltype.Void) +def PyErr_Restore(space, type, value, traceback): + """Set the error indicator from the three objects. If the error indicator is + already set, it is cleared first. If the objects are NULL, the error + indicator is cleared. Do not pass a NULL type and non-NULL value or + traceback. The exception type should be a class. Do not pass an invalid + exception type or value. (Violating these rules will cause subtle problems + later.) This call takes away a reference to each object: you must own a + reference to each object before the call and after the call you no longer own + these references. (If you don't understand this, don't use this function. I + warned you.) + + This function is normally only used by code that needs to save and restore the + error indicator temporarily; use PyErr_Fetch() to save the current + exception state.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], lltype.Void) +def PyErr_SetObject(space, type, value): + """This function is similar to PyErr_SetString() but lets you specify an + arbitrary Python object for the "value" of the exception.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, ...], PyObject) +def PyErr_Format(space, exception, format, ): + """This function sets the error indicator and returns NULL. exception should be + a Python exception (class, not an instance). format should be a string, + containing format codes, similar to printf(). The width.precision + before a format code is parsed, but the width part is ignored. + + % This should be exactly the same as the table in PyString_FromFormat. + + % One should just refer to the other. + + % The descriptions for %zd and %zu are wrong, but the truth is complicated + + % because not all compilers support the %z width modifier -- we fake it + + % when necessary via interpolating PY_FORMAT_SIZE_T. + + % Similar comments apply to the %ll width modifier and + + % PY_FORMAT_LONG_LONG. + + % %u, %lu, %zu should have "new in Python 2.5" blurbs. + + + + + + + + Format Characters + + Type + + Comment + + %% + + n/a + + The literal % character. + + %c + + int + + A single character, + represented as an C int. + + %d + + int + + Exactly equivalent to + printf("%d"). + + %u + + unsigned int + + Exactly equivalent to + printf("%u"). + + %ld + + long + + Exactly equivalent to + printf("%ld"). + + %lu + + unsigned long + + Exactly equivalent to + printf("%lu"). + + %lld + + long long + + Exactly equivalent to + printf("%lld"). + + %llu + + unsigned + long long + + Exactly equivalent to + printf("%llu"). + + %zd + + Py_ssize_t + + Exactly equivalent to + printf("%zd"). + + %zu + + size_t + + Exactly equivalent to + printf("%zu"). + + %i + + int + + Exactly equivalent to + printf("%i"). + + %x + + int + + Exactly equivalent to + printf("%x"). + + %s + + char* + + A null-terminated C character + array. + + %p + + void* + + The hex representation of a C + pointer. Mostly equivalent to + printf("%p") except that + it is guaranteed to start with + the literal 0x regardless + of what the platform's + printf yields. + + An unrecognized format character causes all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + + The "%lld" and "%llu" format specifiers are only available + when HAVE_LONG_LONG is defined. + + Support for "%lld" and "%llu" added. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def PyErr_SetNone(space, type): + """This is a shorthand for PyErr_SetObject(type, Py_None).""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyErr_BadArgument(space, ): + """This is a shorthand for PyErr_SetString(PyExc_TypeError, message), where + message indicates that a built-in operation was invoked with an illegal + argument. It is mostly for internal use.""" + raise NotImplementedError + + at cpython_api([{}], PyObject) +def PyErr_NoMemory(space, ): + """This is a shorthand for PyErr_SetNone(PyExc_MemoryError); it returns NULL + so an object allocation function can write return PyErr_NoMemory(); when it + runs out of memory. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyErr_SetFromErrno(space, type): + """ + + + + This is a convenience function to raise an exception when a C library function + has returned an error and set the C variable errno. It constructs a + tuple object whose first item is the integer errno value and whose + second item is the corresponding error message (gotten from strerror()), + and then calls PyErr_SetObject(type, object). On Unix, when the + errno value is EINTR, indicating an interrupted system call, + this calls PyErr_CheckSignals(), and if that set the error indicator, + leaves it set to that. The function always returns NULL, so a wrapper + function around a system call can write return PyErr_SetFromErrno(type); + when the system call returns an error. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], PyObject) +def PyErr_SetFromErrnoWithFilename(space, type, filename): + """Similar to PyErr_SetFromErrno(), with the additional behavior that if + filename is not NULL, it is passed to the constructor of type as a third + parameter. In the case of exceptions such as IOError and OSError, + this is used to define the filename attribute of the exception instance. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real], PyObject) +def PyErr_SetFromWindowsErr(space, ierr): + """This is a convenience function to raise WindowsError. If called with + ierr of 0, the error code returned by a call to GetLastError() + is used instead. It calls the Win32 function FormatMessage() to retrieve + the Windows description of error code given by ierr or GetLastError(), + then it constructs a tuple object whose first item is the ierr value and whose + second item is the corresponding error message (gotten from + FormatMessage()), and then calls PyErr_SetObject(PyExc_WindowsError, + object). This function always returns NULL. Availability: Windows. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], PyObject) +def PyErr_SetExcFromWindowsErr(space, type, ierr): + """Similar to PyErr_SetFromWindowsErr(), with an additional parameter + specifying the exception type to be raised. Availability: Windows. + + + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, rffi.CCHARP], PyObject) +def PyErr_SetFromWindowsErrWithFilename(space, ierr, filename): + """Similar to PyErr_SetFromWindowsErr(), with the additional behavior that + if filename is not NULL, it is passed to the constructor of + WindowsError as a third parameter. Availability: Windows. + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real, rffi.CCHARP], PyObject) +def PyErr_SetExcFromWindowsErrWithFilename(space, type, ierr, filename): + """Similar to PyErr_SetFromWindowsErrWithFilename(), with an additional + parameter specifying the exception type to be raised. Availability: Windows. + + + Return value: always NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.INT_real], rffi.INT_real) +def PyErr_WarnEx(space, category, message, stacklevel): + """Issue a warning message. The category argument is a warning category (see + below) or NULL; the message argument is a message string. stacklevel is a + positive number giving a number of stack frames; the warning will be issued from + the currently executing line of code in that stack frame. A stacklevel of 1 + is the function calling PyErr_WarnEx(), 2 is the function above that, + and so forth. + + This function normally prints a warning message to sys.stderr; however, it is + also possible that the user has specified that warnings are to be turned into + errors, and in that case this will raise an exception. It is also possible that + the function raises an exception because of a problem with the warning machinery + (the implementation imports the warnings module to do the heavy lifting). + The return value is 0 if no exception is raised, or -1 if an exception + is raised. (It is not possible to determine whether a warning message is + actually printed, nor what the reason is for the exception; this is + intentional.) If an exception is raised, the caller should do its normal + exception handling (for example, Py_DECREF() owned references and return + an error value). + + Warning categories must be subclasses of Warning; the default warning + category is RuntimeWarning. The standard Python warning categories are + available as global variables whose names are PyExc_ followed by the Python + exception name. These have the type PyObject*; they are all class + objects. Their names are PyExc_Warning, PyExc_UserWarning, + PyExc_UnicodeWarning, PyExc_DeprecationWarning, + PyExc_SyntaxWarning, PyExc_RuntimeWarning, and + PyExc_FutureWarning. PyExc_Warning is a subclass of + PyExc_Exception; the other warning categories are subclasses of + PyExc_Warning. + + For information about warning control, see the documentation for the + warnings module and the -W option in the command line + documentation. There is no C API for warning control.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyErr_Warn(space, category, message): + """Issue a warning message. The category argument is a warning category (see + below) or NULL; the message argument is a message string. The warning will + appear to be issued from the function calling PyErr_Warn(), equivalent to + calling PyErr_WarnEx() with a stacklevel of 1. + + Deprecated; use PyErr_WarnEx() instead.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP, rffi.INT_real, rffi.CCHARP, PyObject], rffi.INT_real) +def PyErr_WarnExplicit(space, category, message, filename, lineno, module, registry): + """Issue a warning message with explicit control over all warning attributes. This + is a straightforward wrapper around the Python function + warnings.warn_explicit(), see there for more information. The module + and registry arguments may be set to NULL to get the default effect + described there.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real], rffi.INT_real) +def PyErr_WarnPy3k(space, message, stacklevel): + """Issue a DeprecationWarning with the given message and stacklevel + if the Py_Py3kWarningFlag flag is enabled. + """ + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyErr_CheckSignals(space, ): + """ + + + + This function interacts with Python's signal handling. It checks whether a + signal has been sent to the processes and if so, invokes the corresponding + signal handler. If the signal module is supported, this can invoke a + signal handler written in Python. In all cases, the default effect for + SIGINT is to raise the KeyboardInterrupt exception. If an + exception is raised the error indicator is set and the function returns -1; + otherwise the function returns 0. The error indicator may or may not be + cleared if it was previously set.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyErr_SetInterrupt(space, ): + """ + + + + This function simulates the effect of a SIGINT signal arriving --- the + next time PyErr_CheckSignals() is called, KeyboardInterrupt will + be raised. It may be called without holding the interpreter lock. + + % XXX This was described as obsolete, but is used in + + % thread.interrupt_main() (used from IDLE), so it's still needed.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real], rffi.INT_real) +def PySignal_SetWakeupFd(space, fd): + """This utility function specifies a file descriptor to which a '\0' byte will + be written whenever a signal is received. It returns the previous such file + descriptor. The value -1 disables the feature; this is the initial state. + This is equivalent to signal.set_wakeup_fd() in Python, but without any + error checking. fd should be a valid file descriptor. The function should + only be called from the main thread.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject, PyObject], PyObject) +def PyErr_NewException(space, name, base, dict): + """This utility function creates and returns a new exception object. The name + argument must be the name of the new exception, a C string of the form + module.class. The base and dict arguments are normally NULL. This + creates a class object derived from Exception (accessible in C as + PyExc_Exception). + + The __module__ attribute of the new class is set to the first part (up + to the last dot) of the name argument, and the class name is set to the last + part (after the last dot). The base argument can be used to specify alternate + base classes; it can either be only one class or a tuple of classes. The dict + argument can be used to specify a dictionary of class variables and methods.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, PyObject, PyObject], PyObject) +def PyErr_NewExceptionWithDoc(space, name, doc, base, dict): + """Same as PyErr_NewException(), except that the new exception class can + easily be given a docstring: If doc is non-NULL, it will be used as the + docstring for the exception class. + """ + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def PyErr_WriteUnraisable(space, obj): + """This utility function prints a warning message to sys.stderr when an + exception has been set but it is impossible for the interpreter to actually + raise the exception. It is used, for example, when an exception occurs in an + __del__() method. + + The function is called with a single argument obj that identifies the context + in which the unraisable exception occurred. The repr of obj will be printed in + the warning message.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], rffi.INT_real) +def Py_EnterRecursiveCall(space, where): + """Marks a point where a recursive C-level call is about to be performed. + + If USE_STACKCHECK is defined, this function checks if the the OS + stack overflowed using PyOS_CheckStack(). In this is the case, it + sets a MemoryError and returns a nonzero value. + + The function then checks if the recursion limit is reached. If this is the + case, a RuntimeError is set and a nonzero value is returned. + Otherwise, zero is returned. + + where should be a string such as " in instance check" to be + concatenated to the RuntimeError message caused by the recursion depth + limit.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def Py_LeaveRecursiveCall(space, ): + """Ends a Py_EnterRecursiveCall(). Must be called once for each + successful invocation of Py_EnterRecursiveCall().""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFile_Check(space, p): + """Return true if its argument is a PyFileObject or a subtype of + PyFileObject. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFile_CheckExact(space, p): + """Return true if its argument is a PyFileObject, but not a subtype of + PyFileObject. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP], PyObject) +def PyFile_FromString(space, filename, mode): + """ + + + + On success, return a new file object that is opened on the file given by + filename, with a file mode given by mode, where mode has the same + semantics as the standard C routine fopen(). On failure, return NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject) +def PyFile_FromFile(space, fp, name, mode, (*close)(FILE*)): + """Create a new PyFileObject from the already-open standard C file + pointer, fp. The function close will be called when the file should be + closed. Return NULL on failure.""" + raise NotImplementedError + + at cpython_api([PyObject], {FILE*}) +def PyFile_AsFile(space, p): + """Return the file object associated with p as a FILE*. + + If the caller will ever use the returned FILE* object while + the GIL is released it must also call the PyFile_IncUseCount() and + PyFile_DecUseCount() functions described below as appropriate.""" + raise NotImplementedError + + at cpython_api([{PyFileObject*}], lltype.Void) +def PyFile_IncUseCount(space, p): + """Increments the PyFileObject's internal use count to indicate + that the underlying FILE* is being used. + This prevents Python from calling f_close() on it from another thread. + Callers of this must call PyFile_DecUseCount() when they are + finished with the FILE*. Otherwise the file object will + never be closed by Python. + + The GIL must be held while calling this function. + + The suggested use is to call this after PyFile_AsFile() just before + you release the GIL. + """ + raise NotImplementedError + + at cpython_api([{PyFileObject*}], lltype.Void) +def PyFile_DecUseCount(space, p): + """Decrements the PyFileObject's internal unlocked_count member to + indicate that the caller is done with its own use of the FILE*. + This may only be called to undo a prior call to PyFile_IncUseCount(). + + The GIL must be held while calling this function. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], PyObject) +def PyFile_GetLine(space, p, n): + """ + + + + Equivalent to p.readline([n]), this function reads one line from the + object p. p may be a file object or any object with a readline() + method. If n is 0, exactly one line is read, regardless of the length of + the line. If n is greater than 0, no more than n bytes will be read + from the file; a partial line can be returned. In both cases, an empty string + is returned if the end of the file is reached immediately. If n is less than + 0, however, one line is read regardless of length, but EOFError is + raised if the end of the file is reached immediately.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFile_Name(space, p): + """Return the name of the file specified by p as a string object.""" + raise NotImplementedError + + at cpython_api([{PyFileObject*}, rffi.INT_real], lltype.Void) +def PyFile_SetBufSize(space, p, n): + """ + + + + Available on systems with setvbuf() only. This should only be called + immediately after file object creation.""" + raise NotImplementedError + + at cpython_api([{PyFileObject*}, rffi.CCHARP], rffi.INT_real) +def PyFile_SetEncoding(space, p, enc): + """Set the file's encoding for Unicode output to enc. Return 1 on success and 0 + on failure. + """ + raise NotImplementedError + + at cpython_api([{PyFileObject*}, rffi.CCHARP, {*errors}], rffi.INT_real) +def PyFile_SetEncodingAndErrors(space, p, enc, ): + """Set the file's encoding for Unicode output to enc, and its error + mode to err. Return 1 on success and 0 on failure. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], rffi.INT_real) +def PyFile_SoftSpace(space, p, newflag): + """ + + + + This function exists for internal use by the interpreter. Set the + softspace attribute of p to newflag and return the previous value. + p does not have to be a file object for this function to work properly; any + object is supported (thought its only interesting if the softspace + attribute can be set). This function clears any errors, and will return 0 + as the previous value if the attribute either does not exist or if there were + errors in retrieving it. There is no way to detect errors from this function, + but doing so should not be needed.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real) +def PyFile_WriteObject(space, obj, p, flags): + """ + + + + Write object obj to file object p. The only supported flag for flags is + Py_PRINT_RAW; if given, the str() of the object is written + instead of the repr(). Return 0 on success or -1 on failure; the + appropriate exception will be set.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject], rffi.INT_real) +def PyFile_WriteString(space, s, p): + """Write string s to file object p. Return 0 on success or -1 on + failure; the appropriate exception will be set.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFloat_Check(space, p): + """Return true if its argument is a PyFloatObject or a subtype of + PyFloatObject. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFloat_CheckExact(space, p): + """Return true if its argument is a PyFloatObject, but not a subtype of + PyFloatObject. + """ + raise NotImplementedError + + at cpython_api([PyObject, {char**}], PyObject) +def PyFloat_FromString(space, str, pend): + """Create a PyFloatObject object based on the string value in str, or + NULL on failure. The pend argument is ignored. It remains only for + backward compatibility.""" + raise NotImplementedError + + at cpython_api([PyObject], {double}) +def PyFloat_AS_DOUBLE(space, pyfloat): + """Return a C double representation of the contents of pyfloat, but + without error checking.""" + raise NotImplementedError + + at cpython_api([rffi.VOIDP_real], PyObject) +def PyFloat_GetInfo(space, ): + """Return a structseq instance which contains information about the + precision, minimum and maximum values of a float. It's a thin wrapper + around the header file float.h. + """ + raise NotImplementedError + + at cpython_api([{}], {double}) +def PyFloat_GetMax(space, ): + """Return the maximum representable finite float DBL_MAX as C double. + """ + raise NotImplementedError + + at cpython_api([{}], {double}) +def PyFloat_GetMin(space, ): + """Return the minimum normalized positive float DBL_MIN as C double. + """ + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyFloat_ClearFreeList(space, ): + """Clear the float free list. Return the number of items that could not + be freed. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {PyFloatObject*}], lltype.Void) +def PyFloat_AsString(space, buf, v): + """Convert the argument v to a string, using the same rules as + str(). The length of buf should be at least 100. + + This function is unsafe to call because it writes to a buffer whose + length it does not know. + + Use PyObject_Str() or PyOS_double_to_string() instead.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {PyFloatObject*}], lltype.Void) +def PyFloat_AsReprString(space, buf, v): + """Same as PyFloat_AsString, except uses the same rules as + repr(). The length of buf should be at least 100. + + This function is unsafe to call because it writes to a buffer whose + length it does not know. + + Use PyObject_Repr() or PyOS_double_to_string() instead.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFunction_Check(space, o): + """Return true if o is a function object (has type PyFunction_Type). + The parameter must not be NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyFunction_New(space, code, globals): + """Return a new function object associated with the code object code. globals + must be a dictionary with the global variables accessible to the function. + + The function's docstring, name and __module__ are retrieved from the code + object, the argument defaults and closure are set to NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFunction_GetCode(space, op): + """Return the code object associated with the function object op.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFunction_GetGlobals(space, op): + """Return the globals dictionary associated with the function object op.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFunction_GetModule(space, op): + """Return the __module__ attribute of the function object op. This is normally + a string containing the module name, but can be set to any other object by + Python code.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFunction_GetDefaults(space, op): + """Return the argument default values of the function object op. This can be a + tuple of arguments or NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyFunction_SetDefaults(space, op, defaults): + """Set the argument default values for the function object op. defaults must be + Py_None or a tuple. + + Raises SystemError and returns -1 on failure.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyFunction_GetClosure(space, op): + """Return the closure associated with the function object op. This can be NULL + or a tuple of cell objects.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyFunction_SetClosure(space, op, closure): + """Set the closure associated with the function object op. closure must be + Py_None or a tuple of cell objects. + + Raises SystemError and returns -1 on failure.""" + raise NotImplementedError + + at cpython_api([{TYPE}, PyTypeObjectPtr], {TYPE*}) +def PyObject_GC_New(space, , type): + """Analogous to PyObject_New() but for container objects with the + Py_TPFLAGS_HAVE_GC flag set.""" + raise NotImplementedError + + at cpython_api([{TYPE}, PyTypeObjectPtr, Py_ssize_t], {TYPE*}) +def PyObject_GC_NewVar(space, , type, size): + """Analogous to PyObject_NewVar() but for container objects with the + Py_TPFLAGS_HAVE_GC flag set. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{TYPE}, PyObject, Py_ssize_t], {TYPE*}) +def PyObject_GC_Resize(space, , op, newsize): + """Resize an object allocated by PyObject_NewVar(). Returns the + resized object or NULL on failure. + + This function used an int type for newsize. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def PyObject_GC_Track(space, op): + """Adds the object op to the set of container objects tracked by the + collector. The collector can run at unexpected times so objects must be + valid while being tracked. This should be called once all the fields + followed by the tp_traverse handler become valid, usually near the + end of the constructor.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def _PyObject_GC_TRACK(space, op): + """A macro version of PyObject_GC_Track(). It should not be used for + extension modules.""" + raise NotImplementedError + + at cpython_api([{void*}], lltype.Void) +def PyObject_GC_Del(space, op): + """Releases memory allocated to an object using PyObject_GC_New() or + PyObject_GC_NewVar().""" + raise NotImplementedError + + at cpython_api([{void*}], lltype.Void) +def PyObject_GC_UnTrack(space, op): + """Remove the object op from the set of container objects tracked by the + collector. Note that PyObject_GC_Track() can be called again on + this object to add it back to the set of tracked objects. The deallocator + (tp_dealloc handler) should call this for the object before any of + the fields used by the tp_traverse handler become invalid.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def _PyObject_GC_UNTRACK(space, op): + """A macro version of PyObject_GC_UnTrack(). It should not be used for + extension modules.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def Py_VISIT(space, o): + """Call the visit callback, with arguments o and arg. If visit returns + a non-zero value, then return it. Using this macro, tp_traverse + handlers look like: + + static int + my_traverse(Noddy *self, visitproc visit, void *arg) + { + Py_VISIT(self->foo); + Py_VISIT(self->bar); + return 0; + } + """ + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyGen_Check(space, ): + """Return true if ob is a generator object; ob must not be NULL.""" + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyGen_CheckExact(space, ): + """Return true if ob's type is PyGen_Type is a generator object; ob must not + be NULL.""" + raise NotImplementedError + + at cpython_api([{PyFrameObject*}], PyObject) +def PyGen_New(space, frame): + """Create and return a new generator object based on the frame object. A + reference to frame is stolen by this function. The parameter must not be + NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject) +def PyImport_ImportModule(space, name): + """ + + + + This is a simplified interface to PyImport_ImportModuleEx() below, + leaving the globals and locals arguments set to NULL and level set + to 0. When the name + argument contains a dot (when it specifies a submodule of a package), the + fromlist argument is set to the list ['*'] so that the return value is the + named module rather than the top-level package containing it as would otherwise + be the case. (Unfortunately, this has an additional side effect when name in + fact specifies a subpackage instead of a submodule: the submodules specified in + the package's __all__ variable are loaded.) Return a new reference to the + imported module, or NULL with an exception set on failure. Before Python 2.4, + the module may still be created in the failure case --- examine sys.modules + to find out. Starting with Python 2.4, a failing import of a module no longer + leaves the module in sys.modules. + + Failing imports remove incomplete module objects. + + Always uses absolute imports.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject) +def PyImport_ImportModuleNoBlock(space, name): + """This version of PyImport_ImportModule() does not block. It's intended + to be used in C functions that import other modules to execute a function. + The import may block if another thread holds the import lock. The function + PyImport_ImportModuleNoBlock() never blocks. It first tries to fetch + the module from sys.modules and falls back to PyImport_ImportModule() + unless the lock is held, in which case the function will raise an + ImportError. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject, PyObject, PyObject], PyObject) +def PyImport_ImportModuleEx(space, name, globals, locals, fromlist): + """ + + + + Import a module. This is best described by referring to the built-in Python + function __import__(), as the standard __import__() function calls + this function directly. + + The return value is a new reference to the imported module or top-level package, + or NULL with an exception set on failure (before Python 2.4, the module may + still be created in this case). Like for __import__(), the return value + when a submodule of a package was requested is normally the top-level package, + unless a non-empty fromlist was given. + + Failing imports remove incomplete module objects. + + The function is an alias for PyImport_ImportModuleLevel() with + -1 as level, meaning relative import.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject, PyObject, PyObject, rffi.INT_real], PyObject) +def PyImport_ImportModuleLevel(space, name, globals, locals, fromlist, level): + """Import a module. This is best described by referring to the built-in Python + function __import__(), as the standard __import__() function calls + this function directly. + + The return value is a new reference to the imported module or top-level package, + or NULL with an exception set on failure. Like for __import__(), + the return value when a submodule of a package was requested is normally the + top-level package, unless a non-empty fromlist was given. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyImport_Import(space, name): + """ + + + + This is a higher-level interface that calls the current "import hook function". + It invokes the __import__() function from the __builtins__ of the + current globals. This means that the import is done using whatever import hooks + are installed in the current environment, e.g. by rexec or ihooks. + + Always uses absolute imports.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyImport_ReloadModule(space, m): + """ + + + + Reload a module. This is best described by referring to the built-in Python + function reload(), as the standard reload() function calls this + function directly. Return a new reference to the reloaded module, or NULL + with an exception set on failure (the module still exists in this case).""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject, borrowed=True) +def PyImport_AddModule(space, name): + """Return the module object corresponding to a module name. The name argument + may be of the form package.module. First check the modules dictionary if + there's one there, and if not, create a new one and insert it in the modules + dictionary. Return NULL with an exception set on failure. + + This function does not load or import the module; if the module wasn't already + loaded, you will get an empty module object. Use PyImport_ImportModule() + or one of its variants to import a module. Package structures implied by a + dotted name for name are not created if not already present.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject], PyObject) +def PyImport_ExecCodeModule(space, name, co): + """ + + + + Given a module name (possibly of the form package.module) and a code object + read from a Python bytecode file or obtained from the built-in function + compile(), load the module. Return a new reference to the module object, + or NULL with an exception set if an error occurred. Before Python 2.4, the + module could still be created in error cases. Starting with Python 2.4, name + is removed from sys.modules in error cases, and even if name was already + in sys.modules on entry to PyImport_ExecCodeModule(). Leaving + incompletely initialized modules in sys.modules is dangerous, as imports of + such modules have no way to know that the module object is an unknown (and + probably damaged with respect to the module author's intents) state. + + This function will reload the module if it was already imported. See + PyImport_ReloadModule() for the intended way to reload a module. + + If name points to a dotted name of the form package.module, any package + structures not already created will still not be created. + + name is removed from sys.modules in error cases.""" + raise NotImplementedError + + at cpython_api([{}], {long}) +def PyImport_GetMagicNumber(space, ): + """Return the magic number for Python bytecode files (a.k.a. .pyc and + .pyo files). The magic number should be present in the first four bytes + of the bytecode file, in little-endian byte order.""" + raise NotImplementedError + + at cpython_api([{}], PyObject, borrowed=True) +def PyImport_GetModuleDict(space, ): + """Return the dictionary used for the module administration (a.k.a. + sys.modules). Note that this is a per-interpreter variable.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyImport_GetImporter(space, path): + """Return an importer object for a sys.path/pkg.__path__ item + path, possibly by fetching it from the sys.path_importer_cache + dict. If it wasn't yet cached, traverse sys.path_hooks until a hook + is found that can handle the path item. Return None if no hook could; + this tells our caller it should fall back to the built-in import mechanism. + Cache the result in sys.path_importer_cache. Return a new reference + to the importer object. + """ + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def _PyImport_Init(space, ): + """Initialize the import mechanism. For internal use only.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyImport_Cleanup(space, ): + """Empty the module table. For internal use only.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def _PyImport_Fini(space, ): + """Finalize the import mechanism. For internal use only.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP], PyObject) +def _PyImport_FindExtension(space, , ): + """For internal use only.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP], PyObject) +def _PyImport_FixupExtension(space, , ): + """For internal use only.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], rffi.INT_real) +def PyImport_ImportFrozenModule(space, name): + """Load a frozen module named name. Return 1 for success, 0 if the + module is not found, and -1 with an exception set if the initialization + failed. To access the imported module on a successful load, use + PyImport_ImportModule(). (Note the misnomer --- this function would + reload the module if it was already imported.)""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.VOIDP_real], rffi.INT_real) +def PyImport_AppendInittab(space, name, (*initfunc)(void)): + """Add a single module to the existing table of built-in modules. This is a + convenience wrapper around PyImport_ExtendInittab(), returning -1 if + the table could not be extended. The new module can be imported by the name + name, and uses the function initfunc as the initialization function called + on the first attempted import. This should be called before + Py_Initialize().""" + raise NotImplementedError + + at cpython_api([{struct _inittab*}], rffi.INT_real) +def PyImport_ExtendInittab(space, newtab): + """Add a collection of modules to the table of built-in modules. The newtab + array must end with a sentinel entry which contains NULL for the name + field; failure to provide the sentinel value can result in a memory fault. + Returns 0 on success or -1 if insufficient memory could be allocated to + extend the internal table. In the event of failure, no modules are added to the + internal table. This should be called before Py_Initialize().""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def Py_Initialize(space, ): + """ + + + + Initialize the Python interpreter. In an application embedding Python, this + should be called before using any other Python/C API functions; with the + exception of Py_SetProgramName(), PyEval_InitThreads(), + PyEval_ReleaseLock(), and PyEval_AcquireLock(). This initializes + the table of loaded modules (sys.modules), and creates the fundamental + modules __builtin__, __main__ and sys. It also initializes + the module search path (sys.path). It does not set sys.argv; use + PySys_SetArgv() for that. This is a no-op when called for a second time + (without calling Py_Finalize() first). There is no return value; it is a + fatal error if the initialization fails.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real], lltype.Void) +def Py_InitializeEx(space, initsigs): + """This function works like Py_Initialize() if initsigs is 1. If + initsigs is 0, it skips initialization registration of signal handlers, which + might be useful when Python is embedded. + """ + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def Py_Finalize(space, ): + """Undo all initializations made by Py_Initialize() and subsequent use of + Python/C API functions, and destroy all sub-interpreters (see + Py_NewInterpreter() below) that were created and not yet destroyed since + the last call to Py_Initialize(). Ideally, this frees all memory + allocated by the Python interpreter. This is a no-op when called for a second + time (without calling Py_Initialize() again first). There is no return + value; errors during finalization are ignored. + + This function is provided for a number of reasons. An embedding application + might want to restart Python without having to restart the application itself. + An application that has loaded the Python interpreter from a dynamically + loadable library (or DLL) might want to free all memory allocated by Python + before unloading the DLL. During a hunt for memory leaks in an application a + developer might want to free all memory allocated by Python before exiting from + the application. + + Bugs and caveats: The destruction of modules and objects in modules is done + in random order; this may cause destructors (__del__() methods) to fail + when they depend on other objects (even functions) or modules. Dynamically + loaded extension modules loaded by Python are not unloaded. Small amounts of + memory allocated by the Python interpreter may not be freed (if you find a leak, + please report it). Memory tied up in circular references between objects is not + freed. Some memory allocated by extension modules may not be freed. Some + extensions may not work properly if their initialization routine is called more + than once; this can happen if an application calls Py_Initialize() and + Py_Finalize() more than once.""" + raise NotImplementedError + + at cpython_api([{}], {PyThreadState*}) +def Py_NewInterpreter(space, ): + """ + + + + Create a new sub-interpreter. This is an (almost) totally separate environment + for the execution of Python code. In particular, the new interpreter has + separate, independent versions of all imported modules, including the + fundamental modules __builtin__, __main__ and sys. The + table of loaded modules (sys.modules) and the module search path + (sys.path) are also separate. The new environment has no sys.argv + variable. It has new standard I/O stream file objects sys.stdin, + sys.stdout and sys.stderr (however these refer to the same underlying + FILE structures in the C library). + + The return value points to the first thread state created in the new + sub-interpreter. This thread state is made in the current thread state. + Note that no actual thread is created; see the discussion of thread states + below. If creation of the new interpreter is unsuccessful, NULL is + returned; no exception is set since the exception state is stored in the + current thread state and there may not be a current thread state. (Like all + other Python/C API functions, the global interpreter lock must be held before + calling this function and is still held when it returns; however, unlike most + other Python/C API functions, there needn't be a current thread state on + entry.) + + + + + + Extension modules are shared between (sub-)interpreters as follows: the first + time a particular extension is imported, it is initialized normally, and a + (shallow) copy of its module's dictionary is squirreled away. When the same + extension is imported by another (sub-)interpreter, a new module is initialized + and filled with the contents of this copy; the extension's init function is + not called. Note that this is different from what happens when an extension is + imported after the interpreter has been completely re-initialized by calling + Py_Finalize() and Py_Initialize(); in that case, the extension's + initmodule function is called again. + + + + + + Bugs and caveats: Because sub-interpreters (and the main interpreter) are + part of the same process, the insulation between them isn't perfect --- for + example, using low-level file operations like os.close() they can + (accidentally or maliciously) affect each other's open files. Because of the + way extensions are shared between (sub-)interpreters, some extensions may not + work properly; this is especially likely when the extension makes use of + (static) global variables, or when the extension manipulates its module's + dictionary after its initialization. It is possible to insert objects created + in one sub-interpreter into a namespace of another sub-interpreter; this should + be done with great care to avoid sharing user-defined functions, methods, + instances or classes between sub-interpreters, since import operations executed + by such objects may affect the wrong (sub-)interpreter's dictionary of loaded + modules. (XXX This is a hard-to-fix bug that will be addressed in a future + release.) + + Also note that the use of this functionality is incompatible with extension + modules such as PyObjC and ctypes that use the PyGILState_*() APIs (and + this is inherent in the way the PyGILState_*() functions work). Simple + things may work, but confusing behavior will always be near.""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def Py_EndInterpreter(space, tstate): + """ + + + + Destroy the (sub-)interpreter represented by the given thread state. The given + thread state must be the current thread state. See the discussion of thread + states below. When the call returns, the current thread state is NULL. All + thread states associated with this interpreter are destroyed. (The global + interpreter lock must be held before calling this function and is still held + when it returns.) Py_Finalize() will destroy all sub-interpreters that + haven't been explicitly destroyed at that point.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], lltype.Void) +def Py_SetProgramName(space, name): + """ + + + + This function should be called before Py_Initialize() is called for + the first time, if it is called at all. It tells the interpreter the value + of the argv[0] argument to the main() function of the program. + This is used by Py_GetPath() and some other functions below to find + the Python run-time libraries relative to the interpreter executable. The + default value is 'python'. The argument should point to a + zero-terminated character string in static storage whose contents will not + change for the duration of the program's execution. No code in the Python + interpreter will change the contents of this storage.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetProgramName(space, ): + """ + + + + Return the program name set with Py_SetProgramName(), or the default. + The returned string points into static storage; the caller should not modify its + value.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetPrefix(space, ): + """Return the prefix for installed platform-independent files. This is derived + through a number of complicated rules from the program name set with + Py_SetProgramName() and some environment variables; for example, if the + program name is '/usr/local/bin/python', the prefix is '/usr/local'. The + returned string points into static storage; the caller should not modify its + value. This corresponds to the prefix variable in the top-level + Makefile and the --prefix argument to the configure + script at build time. The value is available to Python code as sys.prefix. + It is only useful on Unix. See also the next function.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetExecPrefix(space, ): + """Return the exec-prefix for installed platform-dependent files. This is + derived through a number of complicated rules from the program name set with + Py_SetProgramName() and some environment variables; for example, if the + program name is '/usr/local/bin/python', the exec-prefix is + '/usr/local'. The returned string points into static storage; the caller + should not modify its value. This corresponds to the exec_prefix + variable in the top-level Makefile and the --exec-prefix + argument to the configure script at build time. The value is + available to Python code as sys.exec_prefix. It is only useful on Unix. + + Background: The exec-prefix differs from the prefix when platform dependent + files (such as executables and shared libraries) are installed in a different + directory tree. In a typical installation, platform dependent files may be + installed in the /usr/local/plat subtree while platform independent may + be installed in /usr/local. + + Generally speaking, a platform is a combination of hardware and software + families, e.g. Sparc machines running the Solaris 2.x operating system are + considered the same platform, but Intel machines running Solaris 2.x are another + platform, and Intel machines running Linux are yet another platform. Different + major revisions of the same operating system generally also form different + platforms. Non-Unix operating systems are a different story; the installation + strategies on those systems are so different that the prefix and exec-prefix are + meaningless, and set to the empty string. Note that compiled Python bytecode + files are platform independent (but not independent from the Python version by + which they were compiled!). + + System administrators will know how to configure the mount or + automount programs to share /usr/local between platforms + while having /usr/local/plat be a different filesystem for each + platform.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetProgramFullPath(space, ): + """ + + + + Return the full program name of the Python executable; this is computed as a + side-effect of deriving the default module search path from the program name + (set by Py_SetProgramName() above). The returned string points into + static storage; the caller should not modify its value. The value is available + to Python code as sys.executable.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetPath(space, ): + """ + + + + Return the default module search path; this is computed from the program name + (set by Py_SetProgramName() above) and some environment variables. + The returned string consists of a series of directory names separated by a + platform dependent delimiter character. The delimiter character is ':' + on Unix and Mac OS X, ';' on Windows. The returned string points into + static storage; the caller should not modify its value. The list + sys.path is initialized with this value on interpreter startup; it + can be (and usually is) modified later to change the search path for loading + modules. + + XXX should give the exact rules""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetVersion(space, ): + """Return the version of this Python interpreter. This is a string that looks + something like + + "1.5 (#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]" + + + + + + The first word (up to the first space character) is the current Python version; + the first three characters are the major and minor version separated by a + period. The returned string points into static storage; the caller should not + modify its value. The value is available to Python code as sys.version.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetPlatform(space, ): + """ + + + + Return the platform identifier for the current platform. On Unix, this is + formed from the "official" name of the operating system, converted to lower + case, followed by the major revision number; e.g., for Solaris 2.x, which is + also known as SunOS 5.x, the value is 'sunos5'. On Mac OS X, it is + 'darwin'. On Windows, it is 'win'. The returned string points into + static storage; the caller should not modify its value. The value is available + to Python code as sys.platform.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetCopyright(space, ): + """Return the official copyright string for the current Python version, for example + + 'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam' + + + + + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as sys.copyright.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetCompiler(space, ): + """Return an indication of the compiler used to build the current Python version, + in square brackets, for example: + + "[GCC 2.7.2.2]" + + + + + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as part of the variable + sys.version.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetBuildInfo(space, ): + """Return information about the sequence number and build date and time of the + current Python interpreter instance, for example + + "#67, Aug 1 1997, 22:34:28" + + + + + + The returned string points into static storage; the caller should not modify its + value. The value is available to Python code as part of the variable + sys.version.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, {char**}], lltype.Void) +def PySys_SetArgv(space, argc, argv): + """ + + + + Set sys.argv based on argc and argv. These parameters are + similar to those passed to the program's main() function with the + difference that the first entry should refer to the script file to be + executed rather than the executable hosting the Python interpreter. If there + isn't a script that will be run, the first entry in argv can be an empty + string. If this function fails to initialize sys.argv, a fatal + condition is signalled using Py_FatalError(). + + This function also prepends the executed script's path to sys.path. + If no script is executed (in the case of calling python -c or just the + interactive interpreter), the empty string is used instead. + + XXX impl. doesn't seem consistent in allowing 0/NULL for the params; + check w/ Guido.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], lltype.Void) +def Py_SetPythonHome(space, home): + """Set the default "home" directory, that is, the location of the standard + Python libraries. The libraries are searched in + home/lib/pythonversion and home/lib/pythonversion. + The argument should point to a zero-terminated character string in static + storage whose contents will not change for the duration of the program's + execution. No code in the Python interpreter will change the contents of + this storage.""" + raise NotImplementedError + + at cpython_api([{}], rffi.CCHARP) +def Py_GetPythonHome(space, ): + """Return the default "home", that is, the value set by a previous call to + Py_SetPythonHome(), or the value of the PYTHONHOME + environment variable if it is set.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyEval_InitThreads(space, ): + """ + + + + Initialize and acquire the global interpreter lock. It should be called in the + main thread before creating a second thread or engaging in any other thread + operations such as PyEval_ReleaseLock() or + PyEval_ReleaseThread(tstate). It is not needed before calling + PyEval_SaveThread() or PyEval_RestoreThread(). + + + + + + This is a no-op when called for a second time. It is safe to call this function + before calling Py_Initialize(). + + + + + + When only the main thread exists, no GIL operations are needed. This is a + common situation (most Python programs do not use threads), and the lock + operations slow the interpreter down a bit. Therefore, the lock is not + created initially. This situation is equivalent to having acquired the lock: + when there is only a single thread, all object accesses are safe. Therefore, + when this function initializes the global interpreter lock, it also acquires + it. Before the Python thread module creates a new thread, knowing + that either it has the lock or the lock hasn't been created yet, it calls + PyEval_InitThreads(). When this call returns, it is guaranteed that + the lock has been created and that the calling thread has acquired it. + + It is not safe to call this function when it is unknown which thread (if + any) currently has the global interpreter lock. + + This function is not available when thread support is disabled at compile time.""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyEval_ThreadsInitialized(space, ): + """Returns a non-zero value if PyEval_InitThreads() has been called. This + function can be called without holding the GIL, and therefore can be used to + avoid calls to the locking API when running single-threaded. This function is + not available when thread support is disabled at compile time. + """ + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyEval_AcquireLock(space, ): + """Acquire the global interpreter lock. The lock must have been created earlier. + If this thread already has the lock, a deadlock ensues. This function is not + available when thread support is disabled at compile time.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyEval_ReleaseLock(space, ): + """Release the global interpreter lock. The lock must have been created earlier. + This function is not available when thread support is disabled at compile time.""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def PyEval_AcquireThread(space, tstate): + """Acquire the global interpreter lock and set the current thread state to + tstate, which should not be NULL. The lock must have been created earlier. + If this thread already has the lock, deadlock ensues. This function is not + available when thread support is disabled at compile time.""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def PyEval_ReleaseThread(space, tstate): + """Reset the current thread state to NULL and release the global interpreter + lock. The lock must have been created earlier and must be held by the current + thread. The tstate argument, which must not be NULL, is only used to check + that it represents the current thread state --- if it isn't, a fatal error is + reported. This function is not available when thread support is disabled at + compile time.""" + raise NotImplementedError + + at cpython_api([{}], {PyThreadState*}) +def PyEval_SaveThread(space, ): + """Release the global interpreter lock (if it has been created and thread + support is enabled) and reset the thread state to NULL, returning the + previous thread state (which is not NULL). If the lock has been created, + the current thread must have acquired it. (This function is available even + when thread support is disabled at compile time.)""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def PyEval_RestoreThread(space, tstate): + """Acquire the global interpreter lock (if it has been created and thread + support is enabled) and set the thread state to tstate, which must not be + NULL. If the lock has been created, the current thread must not have + acquired it, otherwise deadlock ensues. (This function is available even + when thread support is disabled at compile time.)""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyEval_ReInitThreads(space, ): + """This function is called from PyOS_AfterFork() to ensure that newly + created child processes don't hold locks referring to threads which + are not running in the child process.""" + raise NotImplementedError + + at cpython_api([{}], {PyInterpreterState*}) +def PyInterpreterState_New(space, ): + """Create a new interpreter state object. The global interpreter lock need not + be held, but may be held if it is necessary to serialize calls to this + function.""" + raise NotImplementedError + + at cpython_api([{PyInterpreterState*}], lltype.Void) +def PyInterpreterState_Clear(space, interp): + """Reset all information in an interpreter state object. The global interpreter + lock must be held.""" + raise NotImplementedError + + at cpython_api([{PyInterpreterState*}], lltype.Void) +def PyInterpreterState_Delete(space, interp): + """Destroy an interpreter state object. The global interpreter lock need not be + held. The interpreter state must have been reset with a previous call to + PyInterpreterState_Clear().""" + raise NotImplementedError + + at cpython_api([{PyInterpreterState*}], {PyThreadState*}) +def PyThreadState_New(space, interp): + """Create a new thread state object belonging to the given interpreter object. + The global interpreter lock need not be held, but may be held if it is + necessary to serialize calls to this function.""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def PyThreadState_Clear(space, tstate): + """Reset all information in a thread state object. The global interpreter lock + must be held.""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], lltype.Void) +def PyThreadState_Delete(space, tstate): + """Destroy a thread state object. The global interpreter lock need not be held. + The thread state must have been reset with a previous call to + PyThreadState_Clear().""" + raise NotImplementedError + + at cpython_api([{}], {PyThreadState*}) +def PyThreadState_Get(space, ): + """Return the current thread state. The global interpreter lock must be held. + When the current thread state is NULL, this issues a fatal error (so that + the caller needn't check for NULL).""" + raise NotImplementedError + + at cpython_api([{PyThreadState*}], {PyThreadState*}) +def PyThreadState_Swap(space, tstate): + """Swap the current thread state with the thread state given by the argument + tstate, which may be NULL. The global interpreter lock must be held.""" + raise NotImplementedError + + at cpython_api([{}], PyObject, borrowed=True) +def PyThreadState_GetDict(space, ): + """Return a dictionary in which extensions can store thread-specific state + information. Each extension should use a unique key to use to store state in + the dictionary. It is okay to call this function when no current thread state + is available. If this function returns NULL, no exception has been raised and + the caller should assume no current thread state is available. + + Previously this could only be called when a current thread is active, and NULL + meant that an exception was raised.""" + raise NotImplementedError + + at cpython_api([{long}, PyObject], rffi.INT_real) +def PyThreadState_SetAsyncExc(space, id, exc): + """Asynchronously raise an exception in a thread. The id argument is the thread + id of the target thread; exc is the exception object to be raised. This + function does not steal any references to exc. To prevent naive misuse, you + must write your own C extension to call this. Must be called with the GIL held. + Returns the number of thread states modified; this is normally one, but will be + zero if the thread id isn't found. If exc is NULL, the pending + exception (if any) for the thread is cleared. This raises no exceptions. + """ + raise NotImplementedError + + at cpython_api([{}], {PyGILState_STATE}) +def PyGILState_Ensure(space, ): + """Ensure that the current thread is ready to call the Python C API regardless + of the current state of Python, or of the global interpreter lock. This may + be called as many times as desired by a thread as long as each call is + matched with a call to PyGILState_Release(). In general, other + thread-related APIs may be used between PyGILState_Ensure() and + PyGILState_Release() calls as long as the thread state is restored to + its previous state before the Release(). For example, normal usage of the + Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros is + acceptable. + + The return value is an opaque "handle" to the thread state when + PyGILState_Ensure() was called, and must be passed to + PyGILState_Release() to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles cannot be shared - each + unique call to PyGILState_Ensure() must save the handle for its call + to PyGILState_Release(). + + When the function returns, the current thread will hold the GIL. Failure is a + fatal error. + """ + raise NotImplementedError + + at cpython_api([{PyGILState_STATE}], lltype.Void) +def PyGILState_Release(space, ): + """Release any resources previously acquired. After this call, Python's state will + be the same as it was prior to the corresponding PyGILState_Ensure() call + (but generally this state will be unknown to the caller, hence the use of the + GILState API.) + + Every call to PyGILState_Ensure() must be matched by a call to + PyGILState_Release() on the same thread. + """ + raise NotImplementedError + + at cpython_api([{int (*func)(void*}, {void*}], lltype.Void) +def Py_AddPendingCall(space, , arg)): + """ + + + + Post a notification to the Python main thread. If successful, func will be + called with the argument arg at the earliest convenience. func will be + called having the global interpreter lock held and can thus use the full + Python API and can take any action such as setting object attributes to + signal IO completion. It must return 0 on success, or -1 signalling an + exception. The notification function won't be interrupted to perform another + asynchronous notification recursively, but it can still be interrupted to + switch threads if the global interpreter lock is released, for example, if it + calls back into Python code. + + This function returns 0 on success in which case the notification has been + scheduled. Otherwise, for example if the notification buffer is full, it + returns -1 without setting any exception. + + This function can be called on any thread, be it a Python thread or some + other system thread. If it is a Python thread, it doesn't matter if it holds + the global interpreter lock or not. + """ + raise NotImplementedError + + at cpython_api([{Py_tracefunc}, PyObject], lltype.Void) +def PyEval_SetProfile(space, func, obj): + """Set the profiler function to func. The obj parameter is passed to the + function as its first parameter, and may be any Python object, or NULL. If + the profile function needs to maintain state, using a different value for obj + for each thread provides a convenient and thread-safe place to store it. The + profile function is called for all monitored events except the line-number + events.""" + raise NotImplementedError + + at cpython_api([{Py_tracefunc}, PyObject], lltype.Void) +def PyEval_SetTrace(space, func, obj): + """Set the tracing function to func. This is similar to + PyEval_SetProfile(), except the tracing function does receive line-number + events.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyEval_GetCallStats(space, self): + """Return a tuple of function call counts. There are constants defined for the + positions within the tuple: + + + + + + Name + + Value + + PCALL_ALL + + 0 + + PCALL_FUNCTION + + 1 + + PCALL_FAST_FUNCTION + + 2 + + PCALL_FASTER_FUNCTION + + 3 + + PCALL_METHOD + + 4 + + PCALL_BOUND_METHOD + + 5 + + PCALL_CFUNCTION + + 6 + + PCALL_TYPE + + 7 + + PCALL_GENERATOR + + 8 + + PCALL_OTHER + + 9 + + PCALL_POP + + 10 + + PCALL_FAST_FUNCTION means no argument tuple needs to be created. + PCALL_FASTER_FUNCTION means that the fast-path frame setup code is used. + + If there is a method call where the call can be optimized by changing + the argument tuple and calling the function directly, it gets recorded + twice. + + This function is only present if Python is compiled with CALL_PROFILE + defined.""" + raise NotImplementedError + + at cpython_api([{}], {PyInterpreterState*}) +def PyInterpreterState_Head(space, ): + """Return the interpreter state object at the head of the list of all such objects. + """ + raise NotImplementedError + + at cpython_api([{PyInterpreterState*}], {PyInterpreterState*}) +def PyInterpreterState_Next(space, interp): + """Return the next interpreter state object after interp from the list of all + such objects. + """ + raise NotImplementedError + + at cpython_api([{PyInterpreterState*}], {PyThreadState* }) +def PyInterpreterState_ThreadHead(space, interp): + """Return the a pointer to the first PyThreadState object in the list of + threads associated with the interpreter interp. + """ + raise NotImplementedError + + at cpython_api([{PyThreadState*}], {PyThreadState*}) +def PyThreadState_Next(space, tstate): + """Return the next thread state object after tstate from the list of all such + objects belonging to the same PyInterpreterState object. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyInt_Check(space, o): + """Return true if o is of type PyInt_Type or a subtype of + PyInt_Type. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyInt_CheckExact(space, o): + """Return true if o is of type PyInt_Type, but not a subtype of + PyInt_Type. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {char**}, rffi.INT_real], PyObject) +def PyInt_FromString(space, str, pend, base): + """Return a new PyIntObject or PyLongObject based on the string + value in str, which is interpreted according to the radix in base. If + pend is non-NULL, *pend will point to the first character in str which + follows the representation of the number. If base is 0, the radix will be + determined based on the leading characters of str: if str starts with + '0x' or '0X', radix 16 will be used; if str starts with '0', radix + 8 will be used; otherwise radix 10 will be used. If base is not 0, it + must be between 2 and 36, inclusive. Leading spaces are ignored. If + there are no digits, ValueError will be raised. If the string represents + a number too large to be contained within the machine's long int type + and overflow warnings are being suppressed, a PyLongObject will be + returned. If overflow warnings are not being suppressed, NULL will be + returned in this case.""" + raise NotImplementedError + + at cpython_api([{long}], PyObject) +def PyInt_FromLong(space, ival): + """Create a new integer object with a value of ival. + + The current implementation keeps an array of integer objects for all integers + between -5 and 256, when you create an int in that range you actually + just get back a reference to the existing object. So it should be possible to + change the value of 1. I suspect the behaviour of Python in this case is + undefined. :-)""" + raise NotImplementedError + + at cpython_api([Py_ssize_t], PyObject) +def PyInt_FromSsize_t(space, ival): + """Create a new integer object with a value of ival. If the value is larger + than LONG_MAX or smaller than LONG_MIN, a long integer object is + returned. + """ + raise NotImplementedError + + at cpython_api([{size_t}], PyObject) +def PyInt_FromSize_t(space, ival): + """Create a new integer object with a value of ival. If the value exceeds + LONG_MAX, a long integer object is returned. + """ + raise NotImplementedError + + at cpython_api([PyObject], {long}) +def PyInt_AsLong(space, io): + """Will first attempt to cast the object to a PyIntObject, if it is not + already one, and then return its value. If there is an error, -1 is + returned, and the caller should check PyErr_Occurred() to find out whether + there was an error, or whether the value just happened to be -1.""" + raise NotImplementedError + + at cpython_api([PyObject], {long}) +def PyInt_AS_LONG(space, io): + """Return the value of the object io. No error checking is performed.""" + raise NotImplementedError + + at cpython_api([PyObject], {unsigned long}) +def PyInt_AsUnsignedLongMask(space, io): + """Will first attempt to cast the object to a PyIntObject or + PyLongObject, if it is not already one, and then return its value as + unsigned long. This function does not check for overflow. + """ + raise NotImplementedError + + at cpython_api([PyObject], {unsigned PY_LONG_LONG}) +def PyInt_AsUnsignedLongLongMask(space, io): + """Will first attempt to cast the object to a PyIntObject or + PyLongObject, if it is not already one, and then return its value as + unsigned long long, without checking for overflow. + """ + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyInt_AsSsize_t(space, io): + """Will first attempt to cast the object to a PyIntObject or + PyLongObject, if it is not already one, and then return its value as + Py_ssize_t. + """ + raise NotImplementedError + + at cpython_api([{}], {long}) +def PyInt_GetMax(space, ): + """ + + + + Return the system's idea of the largest integer it can handle + (LONG_MAX, as defined in the system header files).""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyInt_ClearFreeList(space, ): + """Clear the integer free list. Return the number of items that could not + be freed. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyIter_Check(space, o): + """Return true if the object o supports the iterator protocol.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyIter_Next(space, o): + """Return the next value from the iteration o. If the object is an iterator, + this retrieves the next value from the iteration, and returns NULL with no + exception set if there are no remaining items. If the object is not an + iterator, TypeError is raised, or if there is an error in retrieving the + item, returns NULL and passes along the exception.""" + raise NotImplementedError + + at cpython_api([{op}], rffi.INT_real) +def PySeqIter_Check(space, ): + """Return true if the type of op is PySeqIter_Type. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PySeqIter_New(space, seq): + """Return an iterator that works with a general sequence object, seq. The + iteration ends when the sequence raises IndexError for the subscripting + operation. + """ + raise NotImplementedError + + at cpython_api([{op}], rffi.INT_real) +def PyCallIter_Check(space, ): + """Return true if the type of op is PyCallIter_Type. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyCallIter_New(space, callable, sentinel): + """Return a new iterator. The first parameter, callable, can be any Python + callable object that can be called with no parameters; each call to it should + return the next item in the iteration. When callable returns a value equal to + sentinel, the iteration will be terminated. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyList_Check(space, p): + """Return true if p is a list object or an instance of a subtype of the list + type. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyList_CheckExact(space, p): + """Return true if p is a list object, but not an instance of a subtype of + the list type. + """ + raise NotImplementedError + + at cpython_api([Py_ssize_t], PyObject) +def PyList_New(space, len): + """Return a new list of length len on success, or NULL on failure. + + If length is greater than zero, the returned list object's items are + set to NULL. Thus you cannot use abstract API functions such as + PySequence_SetItem() or expose the object to Python code before + setting all items to a real object with PyList_SetItem(). + + This function used an int for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyList_Size(space, list): + """ + + + + Return the length of the list object in list; this is equivalent to + len(list) on a list object. + + This function returned an int. This might require changes in + your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyList_GET_SIZE(space, list): + """Macro form of PyList_Size() without error checking. + + This macro returned an int. This might require changes in your + code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) +def PyList_GetItem(space, list, index): + """Return the object at position pos in the list pointed to by p. The + position must be positive, indexing from the end of the list is not + supported. If pos is out of bounds, return NULL and set an + IndexError exception. + + This function used an int for index. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) +def PyList_GET_ITEM(space, list, i): + """Macro form of PyList_GetItem() without error checking. + + This macro used an int for i. This might require changes in + your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real) +def PyList_SetItem(space, list, index, item): + """Set the item at index index in list to item. Return 0 on success + or -1 on failure. + + This function "steals" a reference to item and discards a reference to + an item already in the list at the affected position. + + This function used an int for index. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, PyObject], lltype.Void) +def PyList_SET_ITEM(space, list, i, o): + """Macro form of PyList_SetItem() without error checking. This is + normally only used to fill in new lists where there is no previous content. + + This macro "steals" a reference to item, and, unlike + PyList_SetItem(), does not discard a reference to any item that + it being replaced; any reference in list at position i will be + leaked. + + This macro used an int for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real) +def PyList_Insert(space, list, index, item): + """Insert the item item into list list in front of index index. Return + 0 if successful; return -1 and set an exception if unsuccessful. + Analogous to list.insert(index, item). + + This function used an int for index. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyList_Append(space, list, item): + """Append the object item at the end of list list. Return 0 if + successful; return -1 and set an exception if unsuccessful. Analogous + to list.append(item).""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) +def PyList_GetSlice(space, list, low, high): + """Return a list of the objects in list containing the objects between low + and high. Return NULL and set an exception if unsuccessful. Analogous + to list[low:high]. Negative indices, as when slicing from Python, are not + supported. + + This function used an int for low and high. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, PyObject], rffi.INT_real) +def PyList_SetSlice(space, list, low, high, itemlist): + """Set the slice of list between low and high to the contents of + itemlist. Analogous to list[low:high] = itemlist. The itemlist may + be NULL, indicating the assignment of an empty list (slice deletion). + Return 0 on success, -1 on failure. Negative indices, as when + slicing from Python, are not supported. + + This function used an int for low and high. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyList_Sort(space, list): + """Sort the items of list in place. Return 0 on success, -1 on + failure. This is equivalent to list.sort().""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyList_Reverse(space, list): + """Reverse the items of list in place. Return 0 on success, -1 on + failure. This is the equivalent of list.reverse().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyList_AsTuple(space, list): + """ + + + + Return a new tuple object containing the contents of list; equivalent to + tuple(list).""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyLong_Check(space, p): + """Return true if its argument is a PyLongObject or a subtype of + PyLongObject. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyLong_CheckExact(space, p): + """Return true if its argument is a PyLongObject, but not a subtype of + PyLongObject. + """ + raise NotImplementedError + + at cpython_api([{long}], PyObject) +def PyLong_FromLong(space, v): + """Return a new PyLongObject object from v, or NULL on failure.""" + raise NotImplementedError + + at cpython_api([{unsigned long}], PyObject) +def PyLong_FromUnsignedLong(space, v): + """Return a new PyLongObject object from a C unsigned long, or + NULL on failure.""" + raise NotImplementedError + + at cpython_api([Py_ssize_t], PyObject) +def PyLong_FromSsize_t(space, v): + """Return a new PyLongObject object from a C Py_ssize_t, or + NULL on failure. + """ + raise NotImplementedError + + at cpython_api([{size_t}], PyObject) +def PyLong_FromSize_t(space, v): + """Return a new PyLongObject object from a C size_t, or + NULL on failure. + """ + raise NotImplementedError + + at cpython_api([{PY_LONG_LONG}], PyObject) +def PyLong_FromLongLong(space, v): + """Return a new PyLongObject object from a C long long, or NULL + on failure.""" + raise NotImplementedError + + at cpython_api([{unsigned PY_LONG_LONG}], PyObject) +def PyLong_FromUnsignedLongLong(space, v): + """Return a new PyLongObject object from a C unsigned long long, + or NULL on failure.""" + raise NotImplementedError + + at cpython_api([{double}], PyObject) +def PyLong_FromDouble(space, v): + """Return a new PyLongObject object from the integer part of v, or + NULL on failure.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {char**}, rffi.INT_real], PyObject) +def PyLong_FromString(space, str, pend, base): + """Return a new PyLongObject based on the string value in str, which is + interpreted according to the radix in base. If pend is non-NULL, + *pend will point to the first character in str which follows the + representation of the number. If base is 0, the radix will be determined + based on the leading characters of str: if str starts with '0x' or + '0X', radix 16 will be used; if str starts with '0', radix 8 will be + used; otherwise radix 10 will be used. If base is not 0, it must be + between 2 and 36, inclusive. Leading spaces are ignored. If there are + no digits, ValueError will be raised.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE*}, Py_ssize_t, rffi.INT_real], PyObject) +def PyLong_FromUnicode(space, u, length, base): + """Convert a sequence of Unicode digits to a Python long integer value. The first + parameter, u, points to the first character of the Unicode string, length + gives the number of characters, and base is the radix for the conversion. The + radix must be in the range [2, 36]; if it is out of range, ValueError + will be raised. + + + + This function used an int for length. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{void*}], PyObject) +def PyLong_FromVoidPtr(space, p): + """Create a Python integer or long integer from the pointer p. The pointer value + can be retrieved from the resulting value using PyLong_AsVoidPtr(). + + + + If the integer is larger than LONG_MAX, a positive long integer is returned.""" + raise NotImplementedError + + at cpython_api([PyObject], {long}) +def PyLong_AsLong(space, pylong): + """ + + + + Return a C long representation of the contents of pylong. If + pylong is greater than LONG_MAX, an OverflowError is raised + and -1 will be returned.""" + raise NotImplementedError + + at cpython_api([PyObject, {int*}], {long}) +def PyLong_AsLongAndOverflow(space, pylong, overflow): + """Return a C long representation of the contents of + pylong. If pylong is greater than LONG_MAX or less + than LONG_MIN, set *overflow to 1 or -1, + respectively, and return -1; otherwise, set *overflow to + 0. If any other exception occurs (for example a TypeError or + MemoryError), then -1 will be returned and *overflow will + be 0. + """ + raise NotImplementedError + + at cpython_api([PyObject, {int*}], {PY_LONG_LONG}) +def PyLong_AsLongLongAndOverflow(space, pylong, overflow): + """Return a C long long representation of the contents of + pylong. If pylong is greater than PY_LLONG_MAX or less + than PY_LLONG_MIN, set *overflow to 1 or -1, + respectively, and return -1; otherwise, set *overflow to + 0. If any other exception occurs (for example a TypeError or + MemoryError), then -1 will be returned and *overflow will + be 0. + """ + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyLong_AsSsize_t(space, pylong): + """ + + + + Return a C Py_ssize_t representation of the contents of pylong. If + pylong is greater than PY_SSIZE_T_MAX, an OverflowError is raised + and -1 will be returned. + """ + raise NotImplementedError + + at cpython_api([PyObject], {unsigned long}) +def PyLong_AsUnsignedLong(space, pylong): + """ + + + + Return a C unsigned long representation of the contents of pylong. + If pylong is greater than ULONG_MAX, an OverflowError is + raised.""" + raise NotImplementedError + + at cpython_api([PyObject], {PY_LONG_LONG}) +def PyLong_AsLongLong(space, pylong): + """ + + + + Return a C long long from a Python long integer. If + pylong cannot be represented as a long long, an + OverflowError is raised and -1 is returned. + """ + raise NotImplementedError + + at cpython_api([PyObject], {unsigned PY_LONG_LONG}) +def PyLong_AsUnsignedLongLong(space, pylong): + """ + + + + Return a C unsigned long long from a Python long integer. If + pylong cannot be represented as an unsigned long long, an + OverflowError is raised and (unsigned long long)-1 is + returned. + + + + A negative pylong now raises OverflowError, not + TypeError.""" + raise NotImplementedError + + at cpython_api([PyObject], {unsigned long}) +def PyLong_AsUnsignedLongMask(space, io): + """Return a C unsigned long from a Python long integer, without checking + for overflow. + """ + raise NotImplementedError + + at cpython_api([PyObject], {unsigned PY_LONG_LONG}) +def PyLong_AsUnsignedLongLongMask(space, io): + """Return a C unsigned long long from a Python long integer, without + checking for overflow. + """ + raise NotImplementedError + + at cpython_api([PyObject], {double}) +def PyLong_AsDouble(space, pylong): + """Return a C double representation of the contents of pylong. If + pylong cannot be approximately represented as a double, an + OverflowError exception is raised and -1.0 will be returned.""" + raise NotImplementedError + + at cpython_api([PyObject], {void*}) +def PyLong_AsVoidPtr(space, pylong): + """Convert a Python integer or long integer pylong to a C void pointer. + If pylong cannot be converted, an OverflowError will be raised. This + is only assured to produce a usable void pointer for values created + with PyLong_FromVoidPtr(). + + + + For values outside 0..LONG_MAX, both signed and unsigned integers are accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyMapping_Check(space, o): + """Return 1 if the object provides mapping protocol, and 0 otherwise. This + function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyMapping_Size(space, o): + """ + + + + Returns the number of keys in object o on success, and -1 on failure. For + objects that do not provide mapping protocol, this is equivalent to the Python + expression len(o). + + These functions returned an int type. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyMapping_DelItemString(space, o, key): + """Remove the mapping for object key from the object o. Return -1 on + failure. This is equivalent to the Python statement del o[key].""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyMapping_DelItem(space, o, key): + """Remove the mapping for object key from the object o. Return -1 on + failure. This is equivalent to the Python statement del o[key].""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyMapping_HasKeyString(space, o, key): + """On success, return 1 if the mapping object has the key key and 0 + otherwise. This is equivalent to o[key], returning True on success + and False on an exception. This function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyMapping_HasKey(space, o, key): + """Return 1 if the mapping object has the key key and 0 otherwise. + This is equivalent to o[key], returning True on success and False + on an exception. This function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyMapping_Keys(space, o): + """On success, return a list of the keys in object o. On failure, return NULL. + This is equivalent to the Python expression o.keys().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyMapping_Values(space, o): + """On success, return a list of the values in object o. On failure, return + NULL. This is equivalent to the Python expression o.values().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyMapping_Items(space, o): + """On success, return a list of the items in object o, where each item is a tuple + containing a key-value pair. On failure, return NULL. This is equivalent to + the Python expression o.items().""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], PyObject) +def PyMapping_GetItemString(space, o, key): + """Return element of o corresponding to the object key or NULL on failure. + This is the equivalent of the Python expression o[key].""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real) +def PyMapping_SetItemString(space, o, key, v): + """Map the object key to the value v in object o. Returns -1 on failure. + This is the equivalent of the Python statement o[key] = v.""" + raise NotImplementedError + + at cpython_api([{long}, {FILE*}, rffi.INT_real], lltype.Void) +def PyMarshal_WriteLongToFile(space, value, file, version): + """Marshal a long integer, value, to file. This will only write + the least-significant 32 bits of value; regardless of the size of the + native long type. + + version indicates the file format.""" + raise NotImplementedError + + at cpython_api([PyObject, {FILE*}, rffi.INT_real], lltype.Void) +def PyMarshal_WriteObjectToFile(space, value, file, version): + """Marshal a Python object, value, to file. + + version indicates the file format.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], PyObject) +def PyMarshal_WriteObjectToString(space, value, version): + """Return a string object containing the marshalled representation of value. + + version indicates the file format.""" + raise NotImplementedError + + at cpython_api([{FILE*}], {long}) +def PyMarshal_ReadLongFromFile(space, file): + """Return a C long from the data stream in a FILE* opened + for reading. Only a 32-bit value can be read in using this function, + regardless of the native size of long.""" + raise NotImplementedError + + at cpython_api([{FILE*}], rffi.INT_real) +def PyMarshal_ReadShortFromFile(space, file): + """Return a C short from the data stream in a FILE* opened + for reading. Only a 16-bit value can be read in using this function, + regardless of the native size of short.""" + raise NotImplementedError + + at cpython_api([{FILE*}], PyObject) +def PyMarshal_ReadObjectFromFile(space, file): + """Return a Python object from the data stream in a FILE* opened for + reading. On error, sets the appropriate exception (EOFError or + TypeError) and returns NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}], PyObject) +def PyMarshal_ReadLastObjectFromFile(space, file): + """Return a Python object from the data stream in a FILE* opened for + reading. Unlike PyMarshal_ReadObjectFromFile(), this function + assumes that no further objects will be read from the file, allowing it to + aggressively load file data into memory so that the de-serialization can + operate from data in memory rather than reading a byte at a time from the + file. Only use these variant if you are certain that you won't be reading + anything else from the file. On error, sets the appropriate exception + (EOFError or TypeError) and returns NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t], PyObject) +def PyMarshal_ReadObjectFromString(space, string, len): + """Return a Python object from the data stream in a character buffer + containing len bytes pointed to by string. On error, sets the + appropriate exception (EOFError or TypeError) and returns + NULL. + + This function used an int type for len. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{size_t}], {void*}) +def PyMem_Malloc(space, n): + """Allocates n bytes and returns a pointer of type void* to the + allocated memory, or NULL if the request fails. Requesting zero bytes returns + a distinct non-NULL pointer if possible, as if PyMem_Malloc(1)() had + been called instead. The memory will not have been initialized in any way.""" + raise NotImplementedError + + at cpython_api([{void*}, {size_t}], {void*}) +def PyMem_Realloc(space, p, n): + """Resizes the memory block pointed to by p to n bytes. The contents will be + unchanged to the minimum of the old and the new sizes. If p is NULL, the + call is equivalent to PyMem_Malloc(n)(); else if n is equal to zero, + the memory block is resized but is not freed, and the returned pointer is + non-NULL. Unless p is NULL, it must have been returned by a previous call + to PyMem_Malloc() or PyMem_Realloc(). If the request fails, + PyMem_Realloc() returns NULL and p remains a valid pointer to the + previous memory area.""" + raise NotImplementedError + + at cpython_api([{void*}], lltype.Void) +def PyMem_Free(space, p): + """Frees the memory block pointed to by p, which must have been returned by a + previous call to PyMem_Malloc() or PyMem_Realloc(). Otherwise, or + if PyMem_Free(p)() has been called before, undefined behavior occurs. If + p is NULL, no operation is performed.""" + raise NotImplementedError + + at cpython_api([{TYPE}, {size_t}], {TYPE*}) +def PyMem_New(space, , n): + """Same as PyMem_Malloc(), but allocates (n * sizeof(TYPE)) bytes of + memory. Returns a pointer cast to TYPE*. The memory will not have + been initialized in any way.""" + raise NotImplementedError + + at cpython_api([{void*}, {TYPE}, {size_t}], {TYPE*}) +def PyMem_Resize(space, p, , n): + """Same as PyMem_Realloc(), but the memory block is resized to (n * + sizeof(TYPE)) bytes. Returns a pointer cast to TYPE*. On return, + p will be a pointer to the new memory area, or NULL in the event of + failure. This is a C preprocessor macro; p is always reassigned. Save + the original value of p to avoid losing memory when handling errors.""" + raise NotImplementedError + + at cpython_api([{void*}], lltype.Void) +def PyMem_Del(space, p): + """Same as PyMem_Free().""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyMethod_Check(space, o): + """Return true if o is a method object (has type PyMethod_Type). The + parameter must not be NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PyMethod_New(space, func, self, class): + """Return a new method object, with func being any callable object; this is the + function that will be called when the method is called. If this method should + be bound to an instance, self should be the instance and class should be the + class of self, otherwise self should be NULL and class should be the + class which provides the unbound method..""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_Class(space, meth): + """Return the class object from which the method meth was created; if this was + created from an instance, it will be the class of the instance.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_GET_CLASS(space, meth): + """Macro version of PyMethod_Class() which avoids error checking.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_Function(space, meth): + """Return the function object associated with the method meth.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_GET_FUNCTION(space, meth): + """Macro version of PyMethod_Function() which avoids error checking.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_Self(space, meth): + """Return the instance associated with the method meth if it is bound, otherwise + return NULL.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyMethod_GET_SELF(space, meth): + """Macro version of PyMethod_Self() which avoids error checking.""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyMethod_ClearFreeList(space, ): + """Clear the free list. Return the total number of freed items. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyModule_CheckExact(space, p): + """Return true if p is a module object, but not a subtype of + PyModule_Type. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject) +def PyModule_New(space, name): + """ + + + + Return a new module object with the __name__ attribute set to name. + Only the module's __doc__ and __name__ attributes are filled in; + the caller is responsible for providing a __file__ attribute.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyModule_GetName(space, module): + """ + + + + Return module's __name__ value. If the module does not provide one, + or if it is not a string, SystemError is raised and NULL is returned.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyModule_GetFilename(space, module): + """ + + + + Return the name of the file from which module was loaded using module's + __file__ attribute. If this is not defined, or if it is not a string, + raise SystemError and return NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real) +def PyModule_AddObject(space, module, name, value): + """Add an object to module as name. This is a convenience function which can + be used from the module's initialization function. This steals a reference to + value. Return -1 on error, 0 on success. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, {long}], rffi.INT_real) +def PyModule_AddIntConstant(space, module, name, value): + """Add an integer constant to module as name. This convenience function can be + used from the module's initialization function. Return -1 on error, 0 on + success. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], rffi.INT_real) +def PyModule_AddStringConstant(space, module, name, value): + """Add a string constant to module as name. This convenience function can be + used from the module's initialization function. The string value must be + null-terminated. Return -1 on error, 0 on success. + """ + raise NotImplementedError + + at cpython_api([PyObject, {macro}], rffi.INT_real) +def PyModule_AddIntMacro(space, module, ): + """Add an int constant to module. The name and the value are taken from + macro. For example PyModule_AddConstant(module, AF_INET) adds the int + constant AF_INET with the value of AF_INET to module. + Return -1 on error, 0 on success. + """ + raise NotImplementedError + + at cpython_api([PyObject, {macro}], rffi.INT_real) +def PyModule_AddStringMacro(space, module, ): + """Add a string constant to module. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyNumber_Check(space, o): + """Returns 1 if the object o provides numeric protocols, and false otherwise. + This function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Add(space, o1, o2): + """Returns the result of adding o1 and o2, or NULL on failure. This is the + equivalent of the Python expression o1 + o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Subtract(space, o1, o2): + """Returns the result of subtracting o2 from o1, or NULL on failure. This is + the equivalent of the Python expression o1 - o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Multiply(space, o1, o2): + """Returns the result of multiplying o1 and o2, or NULL on failure. This is + the equivalent of the Python expression o1 * o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Divide(space, o1, o2): + """Returns the result of dividing o1 by o2, or NULL on failure. This is the + equivalent of the Python expression o1 / o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_FloorDivide(space, o1, o2): + """Return the floor of o1 divided by o2, or NULL on failure. This is + equivalent to the "classic" division of integers. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_TrueDivide(space, o1, o2): + """Return a reasonable approximation for the mathematical value of o1 divided by + o2, or NULL on failure. The return value is "approximate" because binary + floating point numbers are approximate; it is not possible to represent all real + numbers in base two. This function can return a floating point value when + passed two integers. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Remainder(space, o1, o2): + """Returns the remainder of dividing o1 by o2, or NULL on failure. This is + the equivalent of the Python expression o1 % o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Divmod(space, o1, o2): + """ + + + + See the built-in function divmod(). Returns NULL on failure. This is + the equivalent of the Python expression divmod(o1, o2).""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PyNumber_Power(space, o1, o2, o3): + """ + + + + See the built-in function pow(). Returns NULL on failure. This is the + equivalent of the Python expression pow(o1, o2, o3), where o3 is optional. + If o3 is to be ignored, pass Py_None in its place (passing NULL for + o3 would cause an illegal memory access).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Negative(space, o): + """Returns the negation of o on success, or NULL on failure. This is the + equivalent of the Python expression -o.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Positive(space, o): + """Returns o on success, or NULL on failure. This is the equivalent of the + Python expression +o.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Absolute(space, o): + """ + + + + Returns the absolute value of o, or NULL on failure. This is the equivalent + of the Python expression abs(o).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Invert(space, o): + """Returns the bitwise negation of o on success, or NULL on failure. This is + the equivalent of the Python expression ~o.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Lshift(space, o1, o2): + """Returns the result of left shifting o1 by o2 on success, or NULL on + failure. This is the equivalent of the Python expression o1 << o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Rshift(space, o1, o2): + """Returns the result of right shifting o1 by o2 on success, or NULL on + failure. This is the equivalent of the Python expression o1 >> o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_And(space, o1, o2): + """Returns the "bitwise and" of o1 and o2 on success and NULL on failure. + This is the equivalent of the Python expression o1 & o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Xor(space, o1, o2): + """Returns the "bitwise exclusive or" of o1 by o2 on success, or NULL on + failure. This is the equivalent of the Python expression o1 ^ o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_Or(space, o1, o2): + """Returns the "bitwise or" of o1 and o2 on success, or NULL on failure. + This is the equivalent of the Python expression o1 | o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceAdd(space, o1, o2): + """Returns the result of adding o1 and o2, or NULL on failure. The operation + is done in-place when o1 supports it. This is the equivalent of the Python + statement o1 += o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceSubtract(space, o1, o2): + """Returns the result of subtracting o2 from o1, or NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 -= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceMultiply(space, o1, o2): + """Returns the result of multiplying o1 and o2, or NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 *= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceDivide(space, o1, o2): + """Returns the result of dividing o1 by o2, or NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 /= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceFloorDivide(space, o1, o2): + """Returns the mathematical floor of dividing o1 by o2, or NULL on failure. + The operation is done in-place when o1 supports it. This is the equivalent + of the Python statement o1 //= o2. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceTrueDivide(space, o1, o2): + """Return a reasonable approximation for the mathematical value of o1 divided by + o2, or NULL on failure. The return value is "approximate" because binary + floating point numbers are approximate; it is not possible to represent all real + numbers in base two. This function can return a floating point value when + passed two integers. The operation is done in-place when o1 supports it. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceRemainder(space, o1, o2): + """Returns the remainder of dividing o1 by o2, or NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 %= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PyNumber_InPlacePower(space, o1, o2, o3): + """ + + + + See the built-in function pow(). Returns NULL on failure. The operation + is done in-place when o1 supports it. This is the equivalent of the Python + statement o1 **= o2 when o3 is Py_None, or an in-place variant of + pow(o1, o2, o3) otherwise. If o3 is to be ignored, pass Py_None + in its place (passing NULL for o3 would cause an illegal memory access).""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceLshift(space, o1, o2): + """Returns the result of left shifting o1 by o2 on success, or NULL on + failure. The operation is done in-place when o1 supports it. This is the + equivalent of the Python statement o1 <<= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceRshift(space, o1, o2): + """Returns the result of right shifting o1 by o2 on success, or NULL on + failure. The operation is done in-place when o1 supports it. This is the + equivalent of the Python statement o1 >>= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceAnd(space, o1, o2): + """Returns the "bitwise and" of o1 and o2 on success and NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 &= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceXor(space, o1, o2): + """Returns the "bitwise exclusive or" of o1 by o2 on success, or NULL on + failure. The operation is done in-place when o1 supports it. This is the + equivalent of the Python statement o1 ^= o2.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyNumber_InPlaceOr(space, o1, o2): + """Returns the "bitwise or" of o1 and o2 on success, or NULL on failure. The + operation is done in-place when o1 supports it. This is the equivalent of + the Python statement o1 |= o2.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, {PyObject**}], rffi.INT_real) +def PyNumber_Coerce(space, p1, p2): + """ + + + + This function takes the addresses of two variables of type PyObject*. + If the objects pointed to by *p1 and *p2 have the same type, increment + their reference count and return 0 (success). If the objects can be + converted to a common numeric type, replace *p1 and *p2 by their + converted value (with 'new' reference counts), and return 0. If no + conversion is possible, or if some other error occurs, return -1 (failure) + and don't increment the reference counts. The call PyNumber_Coerce(&o1, + &o2) is equivalent to the Python statement o1, o2 = coerce(o1, o2).""" + raise NotImplementedError + + at cpython_api([{PyObject**}, {PyObject**}], rffi.INT_real) +def PyNumber_CoerceEx(space, p1, p2): + """This function is similar to PyNumber_Coerce(), except that it returns + 1 when the conversion is not possible and when no error is raised. + Reference counts are still not increased in this case.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Int(space, o): + """ + + + + Returns the o converted to an integer object on success, or NULL on failure. + If the argument is outside the integer range a long object will be returned + instead. This is the equivalent of the Python expression int(o).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Long(space, o): + """ + + + + Returns the o converted to a long integer object on success, or NULL on + failure. This is the equivalent of the Python expression long(o).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Float(space, o): + """ + + + + Returns the o converted to a float object on success, or NULL on failure. + This is the equivalent of the Python expression float(o).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyNumber_Index(space, o): + """Returns the o converted to a Python int or long on success or NULL with a + TypeError exception raised on failure. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], PyObject) +def PyNumber_ToBase(space, n, base): + """Returns the integer n converted to base as a string with a base + marker of '0b', '0o', or '0x' if applicable. When + base is not 2, 8, 10, or 16, the format is 'x#num' where x is the + base. If n is not an int object, it is converted with + PyNumber_Index() first. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], Py_ssize_t) +def PyNumber_AsSsize_t(space, o, exc): + """Returns o converted to a Py_ssize_t value if o can be interpreted as an + integer. If o can be converted to a Python int or long but the attempt to + convert to a Py_ssize_t value would raise an OverflowError, then the + exc argument is the type of exception that will be raised (usually + IndexError or OverflowError). If exc is NULL, then the + exception is cleared and the value is clipped to PY_SSIZE_T_MIN for a negative + integer or PY_SSIZE_T_MAX for a positive integer. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyIndex_Check(space, o): + """Returns True if o is an index integer (has the nb_index slot of the + tp_as_number structure filled in). + """ + raise NotImplementedError + + at cpython_api([PyObject, {const char**}, Py_ssize_t], rffi.INT_real) +def PyObject_AsCharBuffer(space, obj, buffer, buffer_len): + """Returns a pointer to a read-only memory location usable as character-based + input. The obj argument must support the single-segment character buffer + interface. On success, returns 0, sets buffer to the memory location + and buffer_len to the buffer length. Returns -1 and sets a + TypeError on error. + + + + This function used an int * type for buffer_len. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, {const void**}, Py_ssize_t], rffi.INT_real) +def PyObject_AsReadBuffer(space, obj, buffer, buffer_len): + """Returns a pointer to a read-only memory location containing arbitrary data. + The obj argument must support the single-segment readable buffer + interface. On success, returns 0, sets buffer to the memory location + and buffer_len to the buffer length. Returns -1 and sets a + TypeError on error. + + + + This function used an int * type for buffer_len. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyObject_CheckReadBuffer(space, o): + """Returns 1 if o supports the single-segment readable buffer interface. + Otherwise returns 0. + """ + raise NotImplementedError + + at cpython_api([PyObject, {void**}, Py_ssize_t], rffi.INT_real) +def PyObject_AsWriteBuffer(space, obj, buffer, buffer_len): + """Returns a pointer to a writeable memory location. The obj argument must + support the single-segment, character buffer interface. On success, + returns 0, sets buffer to the memory location and buffer_len to the + buffer length. Returns -1 and sets a TypeError on error. + + + + This function used an int * type for buffer_len. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, {FILE*}, rffi.INT_real], rffi.INT_real) +def PyObject_Print(space, o, fp, flags): + """Print an object o, on file fp. Returns -1 on error. The flags argument + is used to enable certain printing options. The only option currently supported + is Py_PRINT_RAW; if given, the str() of the object is written + instead of the repr().""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyObject_HasAttrString(space, o, attr_name): + """Returns 1 if o has the attribute attr_name, and 0 otherwise. This + is equivalent to the Python expression hasattr(o, attr_name). This function + always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyObject_GetAttr(space, o, attr_name): + """Retrieve an attribute named attr_name from object o. Returns the attribute + value on success, or NULL on failure. This is the equivalent of the Python + expression o.attr_name.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], PyObject) +def PyObject_GetAttrString(space, o, attr_name): + """Retrieve an attribute named attr_name from object o. Returns the attribute + value on success, or NULL on failure. This is the equivalent of the Python + expression o.attr_name.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyObject_GenericGetAttr(space, o, name): + """Generic attribute getter function that is meant to be put into a type + object's tp_getattro slot. It looks for a descriptor in the dictionary + of classes in the object's MRO as well as an attribute in the object's + __dict__ (if present). As outlined in descriptors, data + descriptors take preference over instance attributes, while non-data + descriptors don't. Otherwise, an AttributeError is raised.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real) +def PyObject_SetAttrString(space, o, attr_name, v): + """Set the value of the attribute named attr_name, for object o, to the value + v. Returns -1 on failure. This is the equivalent of the Python statement + o.attr_name = v.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real) +def PyObject_GenericSetAttr(space, o, name, value): + """Generic attribute setter function that is meant to be put into a type + object's tp_setattro slot. It looks for a data descriptor in the + dictionary of classes in the object's MRO, and if found it takes preference + over setting the attribute in the instance dictionary. Otherwise, the + attribute is set in the object's __dict__ (if present). Otherwise, + an AttributeError is raised and -1 is returned.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_DelAttr(space, o, attr_name): + """Delete attribute named attr_name, for object o. Returns -1 on failure. + This is the equivalent of the Python statement del o.attr_name.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], rffi.INT_real) +def PyObject_DelAttrString(space, o, attr_name): + """Delete attribute named attr_name, for object o. Returns -1 on failure. + This is the equivalent of the Python statement del o.attr_name.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], PyObject) +def PyObject_RichCompare(space, o1, o2, opid): + """Compare the values of o1 and o2 using the operation specified by opid, + which must be one of Py_LT, Py_LE, Py_EQ, + Py_NE, Py_GT, or Py_GE, corresponding to <, + <=, ==, !=, >, or >= respectively. This is the equivalent of + the Python expression o1 op o2, where op is the operator corresponding + to opid. Returns the value of the comparison on success, or NULL on failure.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real) +def PyObject_RichCompareBool(space, o1, o2, opid): + """Compare the values of o1 and o2 using the operation specified by opid, + which must be one of Py_LT, Py_LE, Py_EQ, + Py_NE, Py_GT, or Py_GE, corresponding to <, + <=, ==, !=, >, or >= respectively. Returns -1 on error, + 0 if the result is false, 1 otherwise. This is the equivalent of the + Python expression o1 op o2, where op is the operator corresponding to + opid.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, {int*}], rffi.INT_real) +def PyObject_Cmp(space, o1, o2, result): + """ + + + + Compare the values of o1 and o2 using a routine provided by o1, if one + exists, otherwise with a routine provided by o2. The result of the comparison + is returned in result. Returns -1 on failure. This is the equivalent of + the Python statement result = cmp(o1, o2).""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_Compare(space, o1, o2): + """ + + + + Compare the values of o1 and o2 using a routine provided by o1, if one + exists, otherwise with a routine provided by o2. Returns the result of the + comparison on success. On error, the value returned is undefined; use + PyErr_Occurred() to detect an error. This is equivalent to the Python + expression cmp(o1, o2).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Repr(space, o): + """ + + + + Compute a string representation of object o. Returns the string + representation on success, NULL on failure. This is the equivalent of the + Python expression repr(o). Called by the repr() built-in function and + by reverse quotes.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Str(space, o): + """ + + + + Compute a string representation of object o. Returns the string + representation on success, NULL on failure. This is the equivalent of the + Python expression str(o). Called by the str() built-in function and + by the print statement.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Bytes(space, o): + """ + + + + Compute a bytes representation of object o. In 2.x, this is just a alias + for PyObject_Str().""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Unicode(space, o): + """ + + + + Compute a Unicode string representation of object o. Returns the Unicode + string representation on success, NULL on failure. This is the equivalent of + the Python expression unicode(o). Called by the unicode() built-in + function.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_IsInstance(space, inst, cls): + """Returns 1 if inst is an instance of the class cls or a subclass of + cls, or 0 if not. On error, returns -1 and sets an exception. If + cls is a type object rather than a class object, PyObject_IsInstance() + returns 1 if inst is of type cls. If cls is a tuple, the check will + be done against every entry in cls. The result will be 1 when at least one + of the checks returns 1, otherwise it will be 0. If inst is not a + class instance and cls is neither a type object, nor a class object, nor a + tuple, inst must have a __class__ attribute --- the class relationship + of the value of that attribute with cls will be used to determine the result + of this function. + + + + Support for a tuple as the second argument added.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_IsSubclass(space, derived, cls): + """Returns 1 if the class derived is identical to or derived from the class + cls, otherwise returns 0. In case of an error, returns -1. If cls + is a tuple, the check will be done against every entry in cls. The result will + be 1 when at least one of the checks returns 1, otherwise it will be + 0. If either derived or cls is not an actual class object (or tuple), + this function uses the generic algorithm described above. + + + + Older versions of Python did not support a tuple as the second argument.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyCallable_Check(space, o): + """Determine if the object o is callable. Return 1 if the object is callable + and 0 otherwise. This function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PyObject_Call(space, callable_object, args, kw): + """ + + + + Call a callable Python object callable_object, with arguments given by the + tuple args, and named arguments given by the dictionary kw. If no named + arguments are needed, kw may be NULL. args must not be NULL, use an + empty tuple if no arguments are needed. Returns the result of the call on + success, or NULL on failure. This is the equivalent of the Python expression + apply(callable_object, args, kw) or callable_object(*args, **kw). + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyObject_CallObject(space, callable_object, args): + """ + + + + Call a callable Python object callable_object, with arguments given by the + tuple args. If no arguments are needed, then args may be NULL. Returns + the result of the call on success, or NULL on failure. This is the equivalent + of the Python expression apply(callable_object, args) or + callable_object(*args).""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, ...], PyObject) +def PyObject_CallFunction(space, callable, format, ): + """ + + + + Call a callable Python object callable, with a variable number of C arguments. + The C arguments are described using a Py_BuildValue() style format + string. The format may be NULL, indicating that no arguments are provided. + Returns the result of the call on success, or NULL on failure. This is the + equivalent of the Python expression apply(callable, args) or + callable(*args). Note that if you only pass PyObject * args, + PyObject_CallFunctionObjArgs() is a faster alternative.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP, ...], PyObject) +def PyObject_CallMethod(space, o, method, format, ): + """Call the method named method of object o with a variable number of C + arguments. The C arguments are described by a Py_BuildValue() format + string that should produce a tuple. The format may be NULL, indicating that + no arguments are provided. Returns the result of the call on success, or NULL + on failure. This is the equivalent of the Python expression o.method(args). + Note that if you only pass PyObject * args, + PyObject_CallMethodObjArgs() is a faster alternative.""" + raise NotImplementedError + + at cpython_api([PyObject, ..., {NULL}], PyObject) +def PyObject_CallFunctionObjArgs(space, callable, , ): + """Call a callable Python object callable, with a variable number of + PyObject* arguments. The arguments are provided as a variable number + of parameters followed by NULL. Returns the result of the call on success, or + NULL on failure. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject, ..., {NULL}], PyObject) +def PyObject_CallMethodObjArgs(space, o, name, , ): + """Calls a method of the object o, where the name of the method is given as a + Python string object in name. It is called with a variable number of + PyObject* arguments. The arguments are provided as a variable number + of parameters followed by NULL. Returns the result of the call on success, or + NULL on failure. + """ + raise NotImplementedError + + at cpython_api([PyObject], {long}) +def PyObject_Hash(space, o): + """ + + + + Compute and return the hash value of an object o. On failure, return -1. + This is the equivalent of the Python expression hash(o).""" + raise NotImplementedError + + at cpython_api([PyObject], {long}) +def PyObject_HashNotImplemented(space, o): + """Set a TypeError indicating that type(o) is not hashable and return -1. + This function receives special treatment when stored in a tp_hash slot, + allowing a type to explicitly indicate to the interpreter that it is not + hashable. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Type(space, o): + """ + + + + When o is non-NULL, returns a type object corresponding to the object type + of object o. On failure, raises SystemError and returns NULL. This + is equivalent to the Python expression type(o). This function increments the + reference count of the return value. There's really no reason to use this + function instead of the common expression o->ob_type, which returns a + pointer of type PyTypeObject*, except when the incremented reference + count is needed.""" + raise NotImplementedError + + at cpython_api([PyObject, PyTypeObjectPtr], rffi.INT_real) +def PyObject_TypeCheck(space, o, type): + """Return true if the object o is of type type or a subtype of type. Both + parameters must be non-NULL. + """ + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyObject_Length(space, o): + """ + + + + Return the length of object o. If the object o provides either the sequence + and mapping protocols, the sequence length is returned. On error, -1 is + returned. This is the equivalent to the Python expression len(o). + + These functions returned an int type. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyObject_GetItem(space, o, key): + """Return element of o corresponding to the object key or NULL on failure. + This is the equivalent of the Python expression o[key].""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real) +def PyObject_SetItem(space, o, key, v): + """Map the object key to the value v. Returns -1 on failure. This is the + equivalent of the Python statement o[key] = v.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyObject_DelItem(space, o, key): + """Delete the mapping for key from o. Returns -1 on failure. This is the + equivalent of the Python statement del o[key].""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyObject_AsFileDescriptor(space, o): + """Derives a file descriptor from a Python object. If the object is an integer or + long integer, its value is returned. If not, the object's fileno() method + is called if it exists; the method must return an integer or long integer, which + is returned as the file descriptor value. Returns -1 on failure.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_Dir(space, o): + """This is equivalent to the Python expression dir(o), returning a (possibly + empty) list of strings appropriate for the object argument, or NULL if there + was an error. If the argument is NULL, this is like the Python dir(), + returning the names of the current locals; in this case, if no execution frame + is active then NULL is returned but PyErr_Occurred() will return false.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyObject_GetIter(space, o): + """This is equivalent to the Python expression iter(o). It returns a new + iterator for the object argument, or the object itself if the object is already + an iterator. Raises TypeError and returns NULL if the object cannot be + iterated.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def Py_XINCREF(space, o): + """Increment the reference count for object o. The object may be NULL, in + which case the macro has no effect.""" + raise NotImplementedError + + at cpython_api([PyObject], lltype.Void) +def Py_CLEAR(space, o): + """Decrement the reference count for object o. The object may be NULL, in + which case the macro has no effect; otherwise the effect is the same as for + Py_DECREF(), except that the argument is also set to NULL. The warning + for Py_DECREF() does not apply with respect to the object passed because + the macro carefully uses a temporary variable and sets the argument to NULL + before decrementing its reference count. + + It is a good idea to use this macro whenever decrementing the value of a + variable that might be traversed during garbage collection. + """ + raise NotImplementedError + + at cpython_api([{}], PyObject, borrowed=True) +def PyEval_GetBuiltins(space, ): + """Return a dictionary of the builtins in the current execution frame, + or the interpreter of the thread state if no frame is currently executing.""" + raise NotImplementedError + + at cpython_api([{}], PyObject, borrowed=True) +def PyEval_GetLocals(space, ): + """Return a dictionary of the local variables in the current execution frame, + or NULL if no frame is currently executing.""" + raise NotImplementedError + + at cpython_api([{}], PyObject, borrowed=True) +def PyEval_GetGlobals(space, ): + """Return a dictionary of the global variables in the current execution frame, + or NULL if no frame is currently executing.""" + raise NotImplementedError + + at cpython_api([{}], {PyFrameObject*}, borrowed=True) +def PyEval_GetFrame(space, ): + """Return the current thread state's frame, which is NULL if no frame is + currently executing.""" + raise NotImplementedError + + at cpython_api([{PyFrameObject*}], rffi.INT_real) +def PyFrame_GetLineNumber(space, frame): + """Return the line number that frame is currently executing.""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyEval_GetRestricted(space, ): + """If there is a current frame and it is executing in restricted mode, return true, + otherwise false.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyEval_GetFuncName(space, func): + """Return the name of func if it is a function, class or instance object, else the + name of funcs type.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyEval_GetFuncDesc(space, func): + """Return a description string, depending on the type of func. + Return values include "()" for functions and methods, " constructor", + " instance", and " object". Concatenated with the result of + PyEval_GetFuncName(), the result will be a description of + func.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PySequence_Check(space, o): + """Return 1 if the object provides sequence protocol, and 0 otherwise. + This function always succeeds.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PySequence_Size(space, o): + """ + + + + Returns the number of objects in sequence o on success, and -1 on failure. + For objects that do not provide sequence protocol, this is equivalent to the + Python expression len(o). + + These functions returned an int type. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PySequence_Concat(space, o1, o2): + """Return the concatenation of o1 and o2 on success, and NULL on failure. + This is the equivalent of the Python expression o1 + o2.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject) +def PySequence_Repeat(space, o, count): + """Return the result of repeating sequence object o count times, or NULL on + failure. This is the equivalent of the Python expression o * count. + + This function used an int type for count. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PySequence_InPlaceConcat(space, o1, o2): + """Return the concatenation of o1 and o2 on success, and NULL on failure. + The operation is done in-place when o1 supports it. This is the equivalent + of the Python expression o1 += o2.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject) +def PySequence_InPlaceRepeat(space, o, count): + """Return the result of repeating sequence object o count times, or NULL on + failure. The operation is done in-place when o supports it. This is the + equivalent of the Python expression o *= count. + + This function used an int type for count. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject) +def PySequence_GetItem(space, o, i): + """Return the ith element of o, or NULL on failure. This is the equivalent of + the Python expression o[i]. + + This function used an int type for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) +def PySequence_GetSlice(space, o, i1, i2): + """Return the slice of sequence object o between i1 and i2, or NULL on + failure. This is the equivalent of the Python expression o[i1:i2]. + + This function used an int type for i1 and i2. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real) +def PySequence_SetItem(space, o, i, v): + """Assign object v to the ith element of o. Returns -1 on failure. This + is the equivalent of the Python statement o[i] = v. This function does + not steal a reference to v. + + This function used an int type for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], rffi.INT_real) +def PySequence_DelItem(space, o, i): + """Delete the ith element of object o. Returns -1 on failure. This is the + equivalent of the Python statement del o[i]. + + This function used an int type for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t, PyObject], rffi.INT_real) +def PySequence_SetSlice(space, o, i1, i2, v): + """Assign the sequence object v to the slice in sequence object o from i1 to + i2. This is the equivalent of the Python statement o[i1:i2] = v. + + This function used an int type for i1 and i2. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], rffi.INT_real) +def PySequence_DelSlice(space, o, i1, i2): + """Delete the slice in sequence object o from i1 to i2. Returns -1 on + failure. This is the equivalent of the Python statement del o[i1:i2]. + + This function used an int type for i1 and i2. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], Py_ssize_t) +def PySequence_Count(space, o, value): + """Return the number of occurrences of value in o, that is, return the number + of keys for which o[key] == value. On failure, return -1. This is + equivalent to the Python expression o.count(value). + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PySequence_Contains(space, o, value): + """Determine if o contains value. If an item in o is equal to value, + return 1, otherwise return 0. On error, return -1. This is + equivalent to the Python expression value in o.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], Py_ssize_t) +def PySequence_Index(space, o, value): + """Return the first index i for which o[i] == value. On error, return + -1. This is equivalent to the Python expression o.index(value). + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PySequence_List(space, o): + """Return a list object with the same contents as the arbitrary sequence o. The + returned list is guaranteed to be new.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PySequence_Tuple(space, o): + """ + + + + Return a tuple object with the same contents as the arbitrary sequence o or + NULL on failure. If o is a tuple, a new reference will be returned, + otherwise a tuple will be constructed with the appropriate contents. This is + equivalent to the Python expression tuple(o).""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP], PyObject) +def PySequence_Fast(space, o, m): + """Returns the sequence o as a tuple, unless it is already a tuple or list, in + which case o is returned. Use PySequence_Fast_GET_ITEM() to access the + members of the result. Returns NULL on failure. If the object is not a + sequence, raises TypeError with m as the message text.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) +def PySequence_Fast_GET_ITEM(space, o, i): + """Return the ith element of o, assuming that o was returned by + PySequence_Fast(), o is not NULL, and that i is within bounds. + + This function used an int type for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], {PyObject**}) +def PySequence_Fast_ITEMS(space, o): + """Return the underlying array of PyObject pointers. Assumes that o was returned + by PySequence_Fast() and o is not NULL. + + Note, if a list gets resized, the reallocation may relocate the items array. + So, only use the underlying array pointer in contexts where the sequence + cannot change. + """ + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject) +def PySequence_ITEM(space, o, i): + """Return the ith element of o or NULL on failure. Macro form of + PySequence_GetItem() but without checking that + PySequence_Check(o)() is true and without adjustment for negative + indices. + + + + This function used an int type for i. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PySequence_Fast_GET_SIZE(space, o): + """Returns the length of o, assuming that o was returned by + PySequence_Fast() and that o is not NULL. The size can also be + gotten by calling PySequence_Size() on o, but + PySequence_Fast_GET_SIZE() is faster because it can assume o is a list + or tuple.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PySet_Check(space, p): + """Return true if p is a set object or an instance of a subtype. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFrozenSet_Check(space, p): + """Return true if p is a frozenset object or an instance of a + subtype. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyAnySet_Check(space, p): + """Return true if p is a set object, a frozenset object, or an + instance of a subtype.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyAnySet_CheckExact(space, p): + """Return true if p is a set object or a frozenset object but + not an instance of a subtype.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyFrozenSet_CheckExact(space, p): + """Return true if p is a frozenset object but not an instance of a + subtype.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PySet_New(space, iterable): + """Return a new set containing objects returned by the iterable. The + iterable may be NULL to create a new empty set. Return the new set on + success or NULL on failure. Raise TypeError if iterable is not + actually iterable. The constructor is also useful for copying a set + (c=set(s)).""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyFrozenSet_New(space, iterable): + """Return a new frozenset containing objects returned by the iterable. + The iterable may be NULL to create a new empty frozenset. Return the new + set on success or NULL on failure. Raise TypeError if iterable is + not actually iterable. + + Now guaranteed to return a brand-new frozenset. Formerly, + frozensets of zero-length were a singleton. This got in the way of + building-up new frozensets with PySet_Add().""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PySet_Size(space, anyset): + """ + + + + Return the length of a set or frozenset object. Equivalent to + len(anyset). Raises a PyExc_SystemError if anyset is not a + set, frozenset, or an instance of a subtype. + + This function returned an int. This might require changes in + your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PySet_GET_SIZE(space, anyset): + """Macro form of PySet_Size() without error checking.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PySet_Contains(space, anyset, key): + """Return 1 if found, 0 if not found, and -1 if an error is encountered. Unlike + the Python __contains__() method, this function does not automatically + convert unhashable sets into temporary frozensets. Raise a TypeError if + the key is unhashable. Raise PyExc_SystemError if anyset is not a + set, frozenset, or an instance of a subtype.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PySet_Add(space, set, key): + """Add key to a set instance. Does not apply to frozenset + instances. Return 0 on success or -1 on failure. Raise a TypeError if + the key is unhashable. Raise a MemoryError if there is no room to grow. + Raise a SystemError if set is an not an instance of set or its + subtype. + + Now works with instances of frozenset or its subtypes. + Like PyTuple_SetItem() in that it can be used to fill-in the + values of brand new frozensets before they are exposed to other code.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PySet_Discard(space, set, key): + """Return 1 if found and removed, 0 if not found (no action taken), and -1 if an + error is encountered. Does not raise KeyError for missing keys. Raise a + TypeError if the key is unhashable. Unlike the Python discard() + method, this function does not automatically convert unhashable sets into + temporary frozensets. Raise PyExc_SystemError if set is an not an + instance of set or its subtype.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PySet_Pop(space, set): + """Return a new reference to an arbitrary object in the set, and removes the + object from the set. Return NULL on failure. Raise KeyError if the + set is empty. Raise a SystemError if set is an not an instance of + set or its subtype.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PySet_Clear(space, set): + """Empty an existing set of all elements.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PySlice_Check(space, ob): + """Return true if ob is a slice object; ob must not be NULL.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject], PyObject) +def PySlice_New(space, start, stop, step): + """Return a new slice object with the given values. The start, stop, and + step parameters are used as the values of the slice object attributes of + the same names. Any of the values may be NULL, in which case the + None will be used for the corresponding attribute. Return NULL if + the new object could not be allocated.""" + raise NotImplementedError + + at cpython_api([{PySliceObject*}, Py_ssize_t, Py_ssize_t, Py_ssize_t, Py_ssize_t], rffi.INT_real) +def PySlice_GetIndices(space, slice, length, start, stop, step): + """Retrieve the start, stop and step indices from the slice object slice, + assuming a sequence of length length. Treats indices greater than + length as errors. + + Returns 0 on success and -1 on error with no exception set (unless one of + the indices was not None and failed to be converted to an integer, + in which case -1 is returned with an exception set). + + You probably do not want to use this function. If you want to use slice + objects in versions of Python prior to 2.3, you would probably do well to + incorporate the source of PySlice_GetIndicesEx(), suitably renamed, + in the source of your extension. + + This function used an int type for length and an + int * type for start, stop, and step. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{PySliceObject*}, Py_ssize_t, Py_ssize_t, Py_ssize_t, Py_ssize_t, Py_ssize_t], rffi.INT_real) +def PySlice_GetIndicesEx(space, slice, length, start, stop, step, slicelength): + """Usable replacement for PySlice_GetIndices(). Retrieve the start, + stop, and step indices from the slice object slice assuming a sequence of + length length, and store the length of the slice in slicelength. Out + of bounds indices are clipped in a manner consistent with the handling of + normal slices. + + Returns 0 on success and -1 on error with exception set. + + + + This function used an int type for length and an + int * type for start, stop, step, and slicelength. This + might require changes in your code for properly supporting 64-bit + systems.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyString_Check(space, o): + """Return true if the object o is a string object or an instance of a subtype of + the string type. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyString_CheckExact(space, o): + """Return true if the object o is a string object, but not an instance of a + subtype of the string type. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, ...], PyObject) +def PyString_FromFormat(space, format, ): + """Take a C printf()-style format string and a variable number of + arguments, calculate the size of the resulting Python string and return a string + with the values formatted into it. The variable arguments must be C types and + must correspond exactly to the format characters in the format string. The + following format characters are allowed: + + % This should be exactly the same as the table in PyErr_Format. + + % One should just refer to the other. + + % The descriptions for %zd and %zu are wrong, but the truth is complicated + + % because not all compilers support the %z width modifier -- we fake it + + % when necessary via interpolating PY_FORMAT_SIZE_T. + + % Similar comments apply to the %ll width modifier and + + % PY_FORMAT_LONG_LONG. + + % %u, %lu, %zu should have "new in Python 2.5" blurbs. + + + + + + + + Format Characters + + Type + + Comment + + %% + + n/a + + The literal % character. + + %c + + int + + A single character, + represented as an C int. + + %d + + int + + Exactly equivalent to + printf("%d"). + + %u + + unsigned int + + Exactly equivalent to + printf("%u"). + + %ld + + long + + Exactly equivalent to + printf("%ld"). + + %lu + + unsigned long + + Exactly equivalent to + printf("%lu"). + + %lld + + long long + + Exactly equivalent to + printf("%lld"). + + %llu + + unsigned + long long + + Exactly equivalent to + printf("%llu"). + + %zd + + Py_ssize_t + + Exactly equivalent to + printf("%zd"). + + %zu + + size_t + + Exactly equivalent to + printf("%zu"). + + %i + + int + + Exactly equivalent to + printf("%i"). + + %x + + int + + Exactly equivalent to + printf("%x"). + + %s + + char* + + A null-terminated C character + array. + + %p + + void* + + The hex representation of a C + pointer. Mostly equivalent to + printf("%p") except that + it is guaranteed to start with + the literal 0x regardless + of what the platform's + printf yields. + + An unrecognized format character causes all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + + The "%lld" and "%llu" format specifiers are only available + when HAVE_LONG_LONG is defined. + + Support for "%lld" and "%llu" added.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {va_list}], PyObject) +def PyString_FromFormatV(space, format, vargs): + """Identical to PyString_FromFormat() except that it takes exactly two + arguments.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyString_GET_SIZE(space, string): + """Macro form of PyString_Size() but without error checking. + + This macro returned an int type. This might require changes in + your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyString_AS_STRING(space, string): + """Macro form of PyString_AsString() but without error checking. Only + string objects are supported; no Unicode objects should be passed.""" + raise NotImplementedError + + at cpython_api([PyObject, {char**}, Py_ssize_t], rffi.INT_real) +def PyString_AsStringAndSize(space, obj, buffer, length): + """Return a NUL-terminated representation of the contents of the object obj + through the output variables buffer and length. + + The function accepts both string and Unicode objects as input. For Unicode + objects it returns the default encoded version of the object. If length is + NULL, the resulting buffer may not contain NUL characters; if it does, the + function returns -1 and a TypeError is raised. + + The buffer refers to an internal string buffer of obj, not a copy. The data + must not be modified in any way, unless the string was just created using + PyString_FromStringAndSize(NULL, size). It must not be deallocated. If + string is a Unicode object, this function computes the default encoding of + string and operates on that. If string is not a string object at all, + PyString_AsStringAndSize() returns -1 and raises TypeError. + + This function used an int * type for length. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, PyObject], lltype.Void) +def PyString_Concat(space, string, newpart): + """Create a new string object in *string containing the contents of newpart + appended to string; the caller will own the new reference. The reference to + the old value of string will be stolen. If the new string cannot be created, + the old reference to string will still be discarded and the value of + *string will be set to NULL; the appropriate exception will be set.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, PyObject], lltype.Void) +def PyString_ConcatAndDel(space, string, newpart): + """Create a new string object in *string containing the contents of newpart + appended to string. This version decrements the reference count of newpart.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, Py_ssize_t], rffi.INT_real) +def _PyString_Resize(space, string, newsize): + """A way to resize a string object even though it is "immutable". Only use this to + build up a brand new string object; don't use this if the string may already be + known in other parts of the code. It is an error to call this function if the + refcount on the input string object is not one. Pass the address of an existing + string object as an lvalue (it may be written into), and the new size desired. + On success, *string holds the resized string object and 0 is returned; + the address in *string may differ from its input value. If the reallocation + fails, the original string object at *string is deallocated, *string is + set to NULL, a memory exception is set, and -1 is returned. + + This function used an int type for newsize. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyString_Format(space, format, args): + """Return a new string object from format and args. Analogous to format % + args. The args argument must be a tuple.""" + raise NotImplementedError + + at cpython_api([{PyObject**}], lltype.Void) +def PyString_InternInPlace(space, string): + """Intern the argument *string in place. The argument must be the address of a + pointer variable pointing to a Python string object. If there is an existing + interned string that is the same as *string, it sets *string to it + (decrementing the reference count of the old string object and incrementing the + reference count of the interned string object), otherwise it leaves *string + alone and interns it (incrementing its reference count). (Clarification: even + though there is a lot of talk about reference counts, think of this function as + reference-count-neutral; you own the object after the call if and only if you + owned it before the call.) + + This function is not available in 3.x and does not have a PyBytes alias.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject) +def PyString_InternFromString(space, v): + """A combination of PyString_FromString() and + PyString_InternInPlace(), returning either a new string object that has + been interned, or a new ("owned") reference to an earlier interned string object + with the same value. + + This function is not available in 3.x and does not have a PyBytes alias.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyString_Decode(space, s, size, encoding, errors): + """Create an object by decoding size bytes of the encoded buffer s using the + codec registered for encoding. encoding and errors have the same meaning + as the parameters of the same name in the unicode() built-in function. + The codec to be used is looked up using the Python codec registry. Return + NULL if an exception was raised by the codec. + + This function is not available in 3.x and does not have a PyBytes alias. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyString_AsDecodedObject(space, str, encoding, errors): + """Decode a string object by passing it to the codec registered for encoding and + return the result as Python object. encoding and errors have the same + meaning as the parameters of the same name in the string encode() method. + The codec to be used is looked up using the Python codec registry. Return NULL + if an exception was raised by the codec. + + This function is not available in 3.x and does not have a PyBytes alias.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyString_Encode(space, s, size, encoding, errors): + """Encode the char buffer of the given size by passing it to the codec + registered for encoding and return a Python object. encoding and errors + have the same meaning as the parameters of the same name in the string + encode() method. The codec to be used is looked up using the Python codec + registry. Return NULL if an exception was raised by the codec. + + This function is not available in 3.x and does not have a PyBytes alias. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyString_AsEncodedObject(space, str, encoding, errors): + """Encode a string object using the codec registered for encoding and return the + result as Python object. encoding and errors have the same meaning as the + parameters of the same name in the string encode() method. The codec to be + used is looked up using the Python codec registry. Return NULL if an exception + was raised by the codec. + + This function is not available in 3.x and does not have a PyBytes alias.""" + raise NotImplementedError + + at cpython_api([{PyMethodDef}, PyObject, rffi.CCHARP], PyObject) +def Py_FindMethod(space, table[], ob, name): + """Return a bound method object for an extension type implemented in C. This + can be useful in the implementation of a tp_getattro or + tp_getattr handler that does not use the + PyObject_GenericGetAttr() function.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP], rffi.INT_real) +def Py_FdIsInteractive(space, fp, filename): + """Return true (nonzero) if the standard I/O file fp with name filename is + deemed interactive. This is the case for files for which isatty(fileno(fp)) + is true. If the global flag Py_InteractiveFlag is true, this function + also returns true if the filename pointer is NULL or if the name is equal to + one of the strings '' or '???'.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PyOS_AfterFork(space, ): + """Function to update some internal state after a process fork; this should be + called in the new process if the Python interpreter will continue to be used. + If a new executable is loaded into the new process, this function does not need + to be called.""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyOS_CheckStack(space, ): + """Return true when the interpreter runs out of stack space. This is a reliable + check, but is only available when USE_STACKCHECK is defined (currently + on Windows using the Microsoft Visual C++ compiler). USE_STACKCHECK + will be defined automatically; you should never change the definition in your + own code.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real], {PyOS_sighandler_t}) +def PyOS_getsig(space, i): + """Return the current signal handler for signal i. This is a thin wrapper around + either sigaction() or signal(). Do not call those functions + directly! PyOS_sighandler_t is a typedef alias for void + (*)(int).""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, {PyOS_sighandler_t}], {PyOS_sighandler_t}) +def PyOS_setsig(space, i, h): + """Set the signal handler for signal i to be h; return the old signal handler. + This is a thin wrapper around either sigaction() or signal(). Do + not call those functions directly! PyOS_sighandler_t is a typedef + alias for void (*)(int).""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], PyObject, borrowed=True) +def PySys_GetObject(space, name): + """Return the object name from the sys module or NULL if it does + not exist, without setting an exception.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {FILE*}], {FILE*}) +def PySys_GetFile(space, name, def): + """Return the FILE* associated with the object name in the + sys module, or def if name is not in the module or is not associated + with a FILE*.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, PyObject], rffi.INT_real) +def PySys_SetObject(space, name, v): + """Set name in the sys module to v unless v is NULL, in which + case name is deleted from the sys module. Returns 0 on success, -1 + on error.""" + raise NotImplementedError + + at cpython_api([{}], lltype.Void) +def PySys_ResetWarnOptions(space, ): + """Reset sys.warnoptions to an empty list.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], lltype.Void) +def PySys_AddWarnOption(space, s): + """Append s to sys.warnoptions.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], lltype.Void) +def PySys_SetPath(space, path): + """Set sys.path to a list object of paths found in path which should + be a list of paths separated with the platform's search path delimiter + (: on Unix, ; on Windows).""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, ...], lltype.Void) +def PySys_WriteStdout(space, format, ): + """Write the output string described by format to sys.stdout. No + exceptions are raised, even if truncation occurs (see below). + + format should limit the total size of the formatted output string to + 1000 bytes or less -- after 1000 bytes, the output string is truncated. + In particular, this means that no unrestricted "%s" formats should occur; + these should be limited using "%.s" where is a decimal number + calculated so that plus the maximum size of other formatted text does not + exceed 1000 bytes. Also watch out for "%f", which can print hundreds of + digits for very large numbers. + + If a problem occurs, or sys.stdout is unset, the formatted message + is written to the real (C level) stdout.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, ...], lltype.Void) +def PySys_WriteStderr(space, format, ): + """As above, but write to sys.stderr or stderr instead.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], lltype.Void) +def Py_FatalError(space, message): + """ + + + + Print a fatal error message and kill the process. No cleanup is performed. + This function should only be invoked when a condition is detected that would + make it dangerous to continue using the Python interpreter; e.g., when the + object administration appears to be corrupted. On Unix, the standard C library + function abort() is called which will attempt to produce a core + file.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real], lltype.Void) +def Py_Exit(space, status): + """ + + + + Exit the current process. This calls Py_Finalize() and then calls the + standard C library function exit(status).""" + raise NotImplementedError + + at cpython_api([{void (*func)}], rffi.INT_real) +def Py_AtExit(space, ()): + """ + + + + Register a cleanup function to be called by Py_Finalize(). The cleanup + function will be called with no arguments and should return no value. At most + 32 cleanup functions can be registered. When the registration is successful, + Py_AtExit() returns 0; on failure, it returns -1. The cleanup + function registered last is called first. Each cleanup function will be called + at most once. Since Python's internal finalization will have completed before + the cleanup function, no Python APIs should be called by func.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyTuple_CheckExact(space, p): + """Return true if p is a tuple object, but not an instance of a subtype of the + tuple type. + """ + raise NotImplementedError + + at cpython_api([Py_ssize_t, ...], PyObject) +def PyTuple_Pack(space, n, ): + """Return a new tuple object of size n, or NULL on failure. The tuple values + are initialized to the subsequent n C arguments pointing to Python objects. + PyTuple_Pack(2, a, b) is equivalent to Py_BuildValue("(OO)", a, b). + + + + This function used an int type for n. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyTuple_Size(space, p): + """Take a pointer to a tuple object, and return the size of that tuple. + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyTuple_GET_SIZE(space, p): + """Return the size of the tuple p, which must be non-NULL and point to a tuple; + no error checking is performed. + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) +def PyTuple_GET_ITEM(space, p, pos): + """Like PyTuple_GetItem(), but does no checking of its arguments. + + This function used an int type for pos. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, Py_ssize_t], PyObject) +def PyTuple_GetSlice(space, p, low, high): + """Take a slice of the tuple pointed to by p from low to high and return it + as a new tuple. + + This function used an int type for low and high. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, Py_ssize_t, PyObject], lltype.Void) +def PyTuple_SET_ITEM(space, p, pos, o): + """Like PyTuple_SetItem(), but does no error checking, and should only be + used to fill in brand new tuples. + + This function "steals" a reference to o. + + This function used an int type for pos. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{PyObject**}, Py_ssize_t], rffi.INT_real) +def _PyTuple_Resize(space, p, newsize): + """Can be used to resize a tuple. newsize will be the new length of the tuple. + Because tuples are supposed to be immutable, this should only be used if there + is only one reference to the object. Do not use this if the tuple may already + be known to some other part of the code. The tuple will always grow or shrink + at the end. Think of this as destroying the old tuple and creating a new one, + only more efficiently. Returns 0 on success. Client code should never + assume that the resulting value of *p will be the same as before calling + this function. If the object referenced by *p is replaced, the original + *p is destroyed. On failure, returns -1 and sets *p to NULL, and + raises MemoryError or SystemError. + + Removed unused third parameter, last_is_sticky. + + This function used an int type for newsize. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyTuple_ClearFreeList(space, ): + """Clear the free list. Return the total number of freed items. + """ + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyType_Check(space, o): + """Return true if the object o is a type object, including instances of types + derived from the standard type object. Return false in all other cases.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyType_CheckExact(space, o): + """Return true if the object o is a type object, but not a subtype of the + standard type object. Return false in all other cases. + """ + raise NotImplementedError + + at cpython_api([{}], {unsigned int}) +def PyType_ClearCache(space, ): + """Clear the internal lookup cache. Return the current version tag. + """ + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr], lltype.Void) +def PyType_Modified(space, type): + """Invalidate the internal lookup cache for the type and all of its + subtypes. This function must be called after any manual + modification of the attributes or base classes of the type. + """ + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], rffi.INT_real) +def PyType_HasFeature(space, o, feature): + """Return true if the type object o sets the feature feature. Type features + are denoted by single bit flags.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyType_IS_GC(space, o): + """Return true if the type object includes support for the cycle detector; this + tests the type flag Py_TPFLAGS_HAVE_GC. + """ + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, PyTypeObjectPtr], rffi.INT_real) +def PyType_IsSubtype(space, a, b): + """Return true if a is a subtype of b. + """ + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, Py_ssize_t], PyObject) +def PyType_GenericAlloc(space, type, nitems): + """ + + This function used an int type for nitems. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyTypeObjectPtr, PyObject, PyObject], PyObject) +def PyType_GenericNew(space, type, args, kwds): + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyUnicode_Check(space, o): + """Return true if the object o is a Unicode object or an instance of a Unicode + subtype. + + Allowed subtypes to be accepted.""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.INT_real) +def PyUnicode_CheckExact(space, o): + """Return true if the object o is a Unicode object, but not an instance of a + subtype. + """ + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyUnicode_GET_SIZE(space, o): + """Return the size of the object. o has to be a PyUnicodeObject (not + checked). + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyUnicode_GET_DATA_SIZE(space, o): + """Return the size of the object's internal buffer in bytes. o has to be a + PyUnicodeObject (not checked). + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], {Py_UNICODE*}) +def PyUnicode_AS_UNICODE(space, o): + """Return a pointer to the internal Py_UNICODE buffer of the object. o + has to be a PyUnicodeObject (not checked).""" + raise NotImplementedError + + at cpython_api([PyObject], rffi.CCHARP) +def PyUnicode_AS_DATA(space, o): + """Return a pointer to the internal buffer of the object. o has to be a + PyUnicodeObject (not checked).""" + raise NotImplementedError + + at cpython_api([{}], rffi.INT_real) +def PyUnicode_ClearFreeList(space, ): + """Clear the free list. Return the total number of freed items. + """ + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISSPACE(space, ch): + """Return 1 or 0 depending on whether ch is a whitespace character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISLOWER(space, ch): + """Return 1 or 0 depending on whether ch is a lowercase character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISUPPER(space, ch): + """Return 1 or 0 depending on whether ch is an uppercase character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISTITLE(space, ch): + """Return 1 or 0 depending on whether ch is a titlecase character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISLINEBREAK(space, ch): + """Return 1 or 0 depending on whether ch is a linebreak character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISDECIMAL(space, ch): + """Return 1 or 0 depending on whether ch is a decimal character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISDIGIT(space, ch): + """Return 1 or 0 depending on whether ch is a digit character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISNUMERIC(space, ch): + """Return 1 or 0 depending on whether ch is a numeric character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISALPHA(space, ch): + """Return 1 or 0 depending on whether ch is an alphabetic character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_ISALNUM(space, ch): + """Return 1 or 0 depending on whether ch is an alphanumeric character.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], {Py_UNICODE}) +def Py_UNICODE_TOLOWER(space, ch): + """Return the character ch converted to lower case.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], {Py_UNICODE}) +def Py_UNICODE_TOUPPER(space, ch): + """Return the character ch converted to upper case.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], {Py_UNICODE}) +def Py_UNICODE_TOTITLE(space, ch): + """Return the character ch converted to title case.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_TODECIMAL(space, ch): + """Return the character ch converted to a decimal positive integer. Return + -1 if this is not possible. This macro does not raise exceptions.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], rffi.INT_real) +def Py_UNICODE_TODIGIT(space, ch): + """Return the character ch converted to a single digit integer. Return -1 if + this is not possible. This macro does not raise exceptions.""" + raise NotImplementedError + + at cpython_api([{Py_UNICODE}], {double}) +def Py_UNICODE_TONUMERIC(space, ch): + """Return the character ch converted to a double. Return -1.0 if this is not + possible. This macro does not raise exceptions.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t], PyObject) +def PyUnicode_FromUnicode(space, u, size): + """Create a Unicode Object from the Py_UNICODE buffer u of the given size. u + may be NULL which causes the contents to be undefined. It is the user's + responsibility to fill in the needed data. The buffer is copied into the new + object. If the buffer is not NULL, the return value might be a shared object. + Therefore, modification of the resulting Unicode object is only allowed when u + is NULL. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], {Py_UNICODE*}) +def PyUnicode_AsUnicode(space, unicode): + """Return a read-only pointer to the Unicode object's internal Py_UNICODE + buffer, NULL if unicode is not a Unicode object.""" + raise NotImplementedError + + at cpython_api([PyObject], Py_ssize_t) +def PyUnicode_GetSize(space, unicode): + """Return the length of the Unicode object. + + This function returned an int type. This might require changes + in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyUnicode_FromEncodedObject(space, obj, encoding, errors): + """Coerce an encoded object obj to an Unicode object and return a reference with + incremented refcount. + + String and other char buffer compatible objects are decoded according to the + given encoding and using the error handling defined by errors. Both can be + NULL to have the interface use the default values (see the next section for + details). + + All other objects, including Unicode objects, cause a TypeError to be + set. + + The API returns NULL if there was an error. The caller is responsible for + decref'ing the returned objects.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_FromObject(space, obj): + """Shortcut for PyUnicode_FromEncodedObject(obj, NULL, "strict") which is used + throughout the interpreter whenever coercion to Unicode is needed.""" + raise NotImplementedError + + at cpython_api([{const wchar_t*}, Py_ssize_t], PyObject) +def PyUnicode_FromWideChar(space, w, size): + """Create a Unicode object from the wchar_t buffer w of the given size. + Return NULL on failure. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{PyUnicodeObject*}, {wchar_t*}, Py_ssize_t], Py_ssize_t) +def PyUnicode_AsWideChar(space, unicode, w, size): + """Copy the Unicode object contents into the wchar_t buffer w. At most + size wchar_t characters are copied (excluding a possibly trailing + 0-termination character). Return the number of wchar_t characters + copied or -1 in case of an error. Note that the resulting wchar_t + string may or may not be 0-terminated. It is the responsibility of the caller + to make sure that the wchar_t string is 0-terminated in case this is + required by the application. + + This function returned an int type and used an int + type for size. This might require changes in your code for properly + supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyUnicode_Decode(space, s, size, encoding, errors): + """Create a Unicode object by decoding size bytes of the encoded string s. + encoding and errors have the same meaning as the parameters of the same name + in the unicode() built-in function. The codec to be used is looked up + using the Python codec registry. Return NULL if an exception was raised by + the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyUnicode_Encode(space, s, size, encoding, errors): + """Encode the Py_UNICODE buffer of the given size and return a Python + string object. encoding and errors have the same meaning as the parameters + of the same name in the Unicode encode() method. The codec to be used is + looked up using the Python codec registry. Return NULL if an exception was + raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject) +def PyUnicode_AsEncodedString(space, unicode, encoding, errors): + """Encode a Unicode object and return the result as Python string object. + encoding and errors have the same meaning as the parameters of the same name + in the Unicode encode() method. The codec to be used is looked up using + the Python codec registry. Return NULL if an exception was raised by the + codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeUTF8(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the UTF-8 encoded string + s. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, Py_ssize_t], PyObject) +def PyUnicode_DecodeUTF8Stateful(space, s, size, errors, consumed): + """If consumed is NULL, behave like PyUnicode_DecodeUTF8(). If + consumed is not NULL, trailing incomplete UTF-8 byte sequences will not be + treated as an error. Those bytes will not be decoded and the number of bytes + that have been decoded will be stored in consumed. + + + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_EncodeUTF8(space, s, size, errors): + """Encode the Py_UNICODE buffer of the given size using UTF-8 and return a + Python string object. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsUTF8String(space, unicode): + """Encode a Unicode object using UTF-8 and return the result as Python string + object. Error handling is "strict". Return NULL if an exception was raised + by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, {int*}], PyObject) +def PyUnicode_DecodeUTF32(space, s, size, errors, byteorder): + """Decode length bytes from a UTF-32 encoded buffer string and return the + corresponding Unicode object. errors (if non-NULL) defines the error + handling. It defaults to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the given byte + order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + If *byteorder is zero, and the first four bytes of the input data are a + byte order mark (BOM), the decoder switches to this byte order and the BOM is + not copied into the resulting Unicode string. If *byteorder is -1 or + 1, any byte order mark is copied to the output. + + After completion, *byteorder is set to the current byte order at the end + of input data. + + In a narrow build codepoints outside the BMP will be decoded as surrogate pairs. + + If byteorder is NULL, the codec starts in native order mode. + + Return NULL if an exception was raised by the codec. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, {int*}, Py_ssize_t], PyObject) +def PyUnicode_DecodeUTF32Stateful(space, s, size, errors, byteorder, consumed): + """If consumed is NULL, behave like PyUnicode_DecodeUTF32(). If + consumed is not NULL, PyUnicode_DecodeUTF32Stateful() will not treat + trailing incomplete UTF-32 byte sequences (such as a number of bytes not divisible + by four) as an error. Those bytes will not be decoded and the number of bytes + that have been decoded will be stored in consumed. + """ + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP, rffi.INT_real], PyObject) +def PyUnicode_EncodeUTF32(space, s, size, errors, byteorder): + """Return a Python bytes object holding the UTF-32 encoded value of the Unicode + data in s. Output is written according to the following byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the Unicode BOM + mark (U+FEFF). In the other two modes, no BOM mark is prepended. + + If Py_UNICODE_WIDE is not defined, surrogate pairs will be output + as a single codepoint. + + Return NULL if an exception was raised by the codec. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsUTF32String(space, unicode): + """Return a Python string using the UTF-32 encoding in native byte order. The + string always starts with a BOM mark. Error handling is "strict". Return + NULL if an exception was raised by the codec. + """ + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, {int*}], PyObject) +def PyUnicode_DecodeUTF16(space, s, size, errors, byteorder): + """Decode length bytes from a UTF-16 encoded buffer string and return the + corresponding Unicode object. errors (if non-NULL) defines the error + handling. It defaults to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the given byte + order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + If *byteorder is zero, and the first two bytes of the input data are a + byte order mark (BOM), the decoder switches to this byte order and the BOM is + not copied into the resulting Unicode string. If *byteorder is -1 or + 1, any byte order mark is copied to the output (where it will result in + either a \ufeff or a \ufffe character). + + After completion, *byteorder is set to the current byte order at the end + of input data. + + If byteorder is NULL, the codec starts in native order mode. + + Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, {int*}, Py_ssize_t], PyObject) +def PyUnicode_DecodeUTF16Stateful(space, s, size, errors, byteorder, consumed): + """If consumed is NULL, behave like PyUnicode_DecodeUTF16(). If + consumed is not NULL, PyUnicode_DecodeUTF16Stateful() will not treat + trailing incomplete UTF-16 byte sequences (such as an odd number of bytes or a + split surrogate pair) as an error. Those bytes will not be decoded and the + number of bytes that have been decoded will be stored in consumed. + + + + This function used an int type for size and an int * + type for consumed. This might require changes in your code for + properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP, rffi.INT_real], PyObject) +def PyUnicode_EncodeUTF16(space, s, size, errors, byteorder): + """Return a Python string object holding the UTF-16 encoded value of the Unicode + data in s. Output is written according to the following byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the Unicode BOM + mark (U+FEFF). In the other two modes, no BOM mark is prepended. + + If Py_UNICODE_WIDE is defined, a single Py_UNICODE value may get + represented as a surrogate pair. If it is not defined, each Py_UNICODE + values is interpreted as an UCS-2 character. + + Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsUTF16String(space, unicode): + """Return a Python string using the UTF-16 encoding in native byte order. The + string always starts with a BOM mark. Error handling is "strict". Return + NULL if an exception was raised by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeUnicodeEscape(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the Unicode-Escape encoded + string s. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t], PyObject) +def PyUnicode_EncodeUnicodeEscape(space, s, size): + """Encode the Py_UNICODE buffer of the given size using Unicode-Escape and + return a Python string object. Return NULL if an exception was raised by the + codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsUnicodeEscapeString(space, unicode): + """Encode a Unicode object using Unicode-Escape and return the result as Python + string object. Error handling is "strict". Return NULL if an exception was + raised by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeRawUnicodeEscape(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the Raw-Unicode-Escape + encoded string s. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_EncodeRawUnicodeEscape(space, s, size, errors): + """Encode the Py_UNICODE buffer of the given size using Raw-Unicode-Escape + and return a Python string object. Return NULL if an exception was raised by + the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsRawUnicodeEscapeString(space, unicode): + """Encode a Unicode object using Raw-Unicode-Escape and return the result as + Python string object. Error handling is "strict". Return NULL if an exception + was raised by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeLatin1(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the Latin-1 encoded string + s. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_EncodeLatin1(space, s, size, errors): + """Encode the Py_UNICODE buffer of the given size using Latin-1 and return + a Python string object. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsLatin1String(space, unicode): + """Encode a Unicode object using Latin-1 and return the result as Python string + object. Error handling is "strict". Return NULL if an exception was raised + by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeASCII(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the ASCII encoded string + s. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_EncodeASCII(space, s, size, errors): + """Encode the Py_UNICODE buffer of the given size using ASCII and return a + Python string object. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsASCIIString(space, unicode): + """Encode a Unicode object using ASCII and return the result as Python string + object. Error handling is "strict". Return NULL if an exception was raised + by the codec.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, PyObject, rffi.CCHARP], PyObject) +def PyUnicode_DecodeCharmap(space, s, size, mapping, errors): + """Create a Unicode object by decoding size bytes of the encoded string s using + the given mapping object. Return NULL if an exception was raised by the + codec. If mapping is NULL latin-1 decoding will be done. Else it can be a + dictionary mapping byte or a unicode string, which is treated as a lookup table. + Byte values greater that the length of the string and U+FFFE "characters" are + treated as "undefined mapping". + + Allowed unicode string as mapping argument. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, PyObject, rffi.CCHARP], PyObject) +def PyUnicode_EncodeCharmap(space, s, size, mapping, errors): + """Encode the Py_UNICODE buffer of the given size using the given + mapping object and return a Python string object. Return NULL if an + exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyUnicode_AsCharmapString(space, unicode, mapping): + """Encode a Unicode object using the given mapping object and return the result + as Python string object. Error handling is "strict". Return NULL if an + exception was raised by the codec.""" + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, PyObject, rffi.CCHARP], PyObject) +def PyUnicode_TranslateCharmap(space, s, size, table, errors): + """Translate a Py_UNICODE buffer of the given length by applying a + character mapping table to it and return the resulting Unicode object. Return + NULL when an exception was raised by the codec. + + The mapping table must map Unicode ordinal integers to Unicode ordinal + integers or None (causing deletion of the character). + + Mapping tables need only provide the __getitem__() interface; dictionaries + and sequences work well. Unmapped character ordinals (ones which cause a + LookupError) are left untouched and are copied as-is. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_DecodeMBCS(space, s, size, errors): + """Create a Unicode object by decoding size bytes of the MBCS encoded string s. + Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real, rffi.CCHARP, {int*}], PyObject) +def PyUnicode_DecodeMBCSStateful(space, s, size, errors, consumed): + """If consumed is NULL, behave like PyUnicode_DecodeMBCS(). If + consumed is not NULL, PyUnicode_DecodeMBCSStateful() will not decode + trailing lead byte and the number of bytes that have been decoded will be stored + in consumed. + """ + raise NotImplementedError + + at cpython_api([{const Py_UNICODE*}, Py_ssize_t, rffi.CCHARP], PyObject) +def PyUnicode_EncodeMBCS(space, s, size, errors): + """Encode the Py_UNICODE buffer of the given size using MBCS and return a + Python string object. Return NULL if an exception was raised by the codec. + + This function used an int type for size. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject], PyObject) +def PyUnicode_AsMBCSString(space, unicode): + """Encode a Unicode object using MBCS and return the result as Python string + object. Error handling is "strict". Return NULL if an exception was raised + by the codec.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyUnicode_Concat(space, left, right): + """Concat two strings giving a new Unicode string.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, Py_ssize_t], PyObject) +def PyUnicode_Split(space, s, sep, maxsplit): + """Split a string giving a list of Unicode strings. If sep is NULL, splitting + will be done at all whitespace substrings. Otherwise, splits occur at the given + separator. At most maxsplit splits will be done. If negative, no limit is + set. Separators are not included in the resulting list. + + This function used an int type for maxsplit. This might require + changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, rffi.INT_real], PyObject) +def PyUnicode_Splitlines(space, s, keepend): + """Split a Unicode string at line breaks, returning a list of Unicode strings. + CRLF is considered to be one line break. If keepend is 0, the Line break + characters are not included in the resulting strings.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.CCHARP], PyObject) +def PyUnicode_Translate(space, str, table, errors): + """Translate a string by applying a character mapping table to it and return the + resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode ordinal integers + or None (causing deletion of the character). + + Mapping tables need only provide the __getitem__() interface; dictionaries + and sequences work well. Unmapped character ordinals (ones which cause a + LookupError) are left untouched and are copied as-is. + + errors has the usual meaning for codecs. It may be NULL which indicates to + use the default error handling.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyUnicode_Join(space, separator, seq): + """Join a sequence of strings using the given separator and return the resulting + Unicode string.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], rffi.INT_real) +def PyUnicode_Tailmatch(space, str, substr, start, end, direction): + """Return 1 if substr matches str*[*start:end] at the given tail end + (direction == -1 means to do a prefix match, direction == 1 a suffix match), + 0 otherwise. Return -1 if an error occurred. + + This function used an int type for start and end. This + might require changes in your code for properly supporting 64-bit + systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real], Py_ssize_t) +def PyUnicode_Find(space, str, substr, start, end, direction): + """Return the first position of substr in str*[*start:end] using the given + direction (direction == 1 means to do a forward search, direction == -1 a + backward search). The return value is the index of the first match; a value of + -1 indicates that no match was found, and -2 indicates that an error + occurred and an exception has been set. + + This function used an int type for start and end. This + might require changes in your code for properly supporting 64-bit + systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t], Py_ssize_t) +def PyUnicode_Count(space, str, substr, start, end): + """Return the number of non-overlapping occurrences of substr in + str[start:end]. Return -1 if an error occurred. + + This function returned an int type and used an int + type for start and end. This might require changes in your code for + properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, PyObject, Py_ssize_t], PyObject) +def PyUnicode_Replace(space, str, substr, replstr, maxcount): + """Replace at most maxcount occurrences of substr in str with replstr and + return the resulting Unicode object. maxcount == -1 means replace all + occurrences. + + This function used an int type for maxcount. This might + require changes in your code for properly supporting 64-bit systems.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyUnicode_Compare(space, left, right): + """Compare two strings and return -1, 0, 1 for less than, equal, and greater than, + respectively.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real) +def PyUnicode_RichCompare(space, left, right, op): + """Rich compare two unicode strings and return one of the following: + + NULL in case an exception was raised + + Py_True or Py_False for successful comparisons + + Py_NotImplemented in case the type combination is unknown + + Note that Py_EQ and Py_NE comparisons can cause a + UnicodeWarning in case the conversion of the arguments to Unicode fails + with a UnicodeDecodeError. + + Possible values for op are Py_GT, Py_GE, Py_EQ, + Py_NE, Py_LT, and Py_LE.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyUnicode_Format(space, format, args): + """Return a new string object from format and args; this is analogous to + format % args. The args argument must be a tuple.""" + raise NotImplementedError + + at cpython_api([PyObject, PyObject], rffi.INT_real) +def PyUnicode_Contains(space, container, element): + """Check whether element is contained in container and return true or false + accordingly. + + element has to coerce to a one element Unicode string. -1 is returned if + there was an error.""" + raise NotImplementedError + + at cpython_api([rffi.INT_real, {char**}], rffi.INT_real) +def Py_Main(space, argc, argv): + """The main program for the standard interpreter. This is made available for + programs which embed Python. The argc and argv parameters should be + prepared exactly as those which are passed to a C program's main() + function. It is important to note that the argument list may be modified (but + the contents of the strings pointed to by the argument list are not). The return + value will be the integer passed to the sys.exit() function, 1 if the + interpreter exits due to an exception, or 2 if the parameter list does not + represent a valid Python command line. + + Note that if an otherwise unhandled SystemError is raised, this + function will not return 1, but exit the process, as long as + Py_InspectFlag is not set.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP], rffi.INT_real) +def PyRun_AnyFile(space, fp, filename): + """This is a simplified interface to PyRun_AnyFileExFlags() below, leaving + closeit set to 0 and flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_AnyFileFlags(space, fp, filename, flags): + """This is a simplified interface to PyRun_AnyFileExFlags() below, leaving + the closeit argument set to 0.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real], rffi.INT_real) +def PyRun_AnyFileEx(space, fp, filename, closeit): + """This is a simplified interface to PyRun_AnyFileExFlags() below, leaving + the flags argument set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_AnyFileExFlags(space, fp, filename, closeit, flags): + """If fp refers to a file associated with an interactive device (console or + terminal input or Unix pseudo-terminal), return the value of + PyRun_InteractiveLoop(), otherwise return the result of + PyRun_SimpleFile(). If filename is NULL, this function uses + "???" as the filename.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP], rffi.INT_real) +def PyRun_SimpleString(space, command): + """This is a simplified interface to PyRun_SimpleStringFlags() below, + leaving the PyCompilerFlags* argument set to NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_SimpleStringFlags(space, command, flags): + """Executes the Python source code from command in the __main__ module + according to the flags argument. If __main__ does not already exist, it + is created. Returns 0 on success or -1 if an exception was raised. If + there was an error, there is no way to get the exception information. For the + meaning of flags, see below. + + Note that if an otherwise unhandled SystemError is raised, this + function will not return -1, but exit the process, as long as + Py_InspectFlag is not set.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP], rffi.INT_real) +def PyRun_SimpleFile(space, fp, filename): + """This is a simplified interface to PyRun_SimpleFileExFlags() below, + leaving closeit set to 0 and flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_SimpleFileFlags(space, fp, filename, flags): + """This is a simplified interface to PyRun_SimpleFileExFlags() below, + leaving closeit set to 0.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real], rffi.INT_real) +def PyRun_SimpleFileEx(space, fp, filename, closeit): + """This is a simplified interface to PyRun_SimpleFileExFlags() below, + leaving flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_SimpleFileExFlags(space, fp, filename, closeit, flags): + """Similar to PyRun_SimpleStringFlags(), but the Python source code is read + from fp instead of an in-memory string. filename should be the name of the + file. If closeit is true, the file is closed before PyRun_SimpleFileExFlags + returns.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP], rffi.INT_real) +def PyRun_InteractiveOne(space, fp, filename): + """This is a simplified interface to PyRun_InteractiveOneFlags() below, + leaving flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_InteractiveOneFlags(space, fp, filename, flags): + """Read and execute a single statement from a file associated with an interactive + device according to the flags argument. If filename is NULL, "???" is + used instead. The user will be prompted using sys.ps1 and sys.ps2. + Returns 0 when the input was executed successfully, -1 if there was an + exception, or an error code from the errcode.h include file distributed + as part of Python if there was a parse error. (Note that errcode.h is + not included by Python.h, so must be included specifically if needed.)""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP], rffi.INT_real) +def PyRun_InteractiveLoop(space, fp, filename): + """This is a simplified interface to PyRun_InteractiveLoopFlags() below, + leaving flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, {PyCompilerFlags*}], rffi.INT_real) +def PyRun_InteractiveLoopFlags(space, fp, filename, flags): + """Read and execute statements from a file associated with an interactive device + until EOF is reached. If filename is NULL, "???" is used instead. The + user will be prompted using sys.ps1 and sys.ps2. Returns 0 at EOF.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real], {struct _node*}) +def PyParser_SimpleParseString(space, str, start): + """This is a simplified interface to + PyParser_SimpleParseStringFlagsFilename() below, leaving filename set + to NULL and flags set to 0.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real, rffi.INT_real], {struct _node*}) +def PyParser_SimpleParseStringFlags(space, str, start, flags): + """This is a simplified interface to + PyParser_SimpleParseStringFlagsFilename() below, leaving filename set + to NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, rffi.INT_real], {struct _node*}) +def PyParser_SimpleParseStringFlagsFilename(space, str, filename, start, flags): + """Parse Python source code from str using the start token start according to + the flags argument. The result can be used to create a code object which can + be evaluated efficiently. This is useful if a code fragment must be evaluated + many times.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real], {struct _node*}) +def PyParser_SimpleParseFile(space, fp, filename, start): + """This is a simplified interface to PyParser_SimpleParseFileFlags() below, + leaving flags set to 0""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, rffi.INT_real], {struct _node*}) +def PyParser_SimpleParseFileFlags(space, fp, filename, start, flags): + """Similar to PyParser_SimpleParseStringFlagsFilename(), but the Python + source code is read from fp instead of an in-memory string.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject], PyObject) +def PyRun_String(space, str, start, globals, locals): + """This is a simplified interface to PyRun_StringFlags() below, leaving + flags set to NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject, {PyCompilerFlags*}], PyObject) +def PyRun_StringFlags(space, str, start, globals, locals, flags): + """Execute Python source code from str in the context specified by the + dictionaries globals and locals with the compiler flags specified by + flags. The parameter start specifies the start token that should be used to + parse the source code. + + Returns the result of executing the code as a Python object, or NULL if an + exception was raised.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, PyObject, PyObject], PyObject) +def PyRun_File(space, fp, filename, start, globals, locals): + """This is a simplified interface to PyRun_FileExFlags() below, leaving + closeit set to 0 and flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, rffi.INT_real], PyObject) +def PyRun_FileEx(space, fp, filename, start, globals, locals, closeit): + """This is a simplified interface to PyRun_FileExFlags() below, leaving + flags set to NULL.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, {PyCompilerFlags*}], PyObject) +def PyRun_FileFlags(space, fp, filename, start, globals, locals, flags): + """This is a simplified interface to PyRun_FileExFlags() below, leaving + closeit set to 0.""" + raise NotImplementedError + + at cpython_api([{FILE*}, rffi.CCHARP, rffi.INT_real, PyObject, PyObject, rffi.INT_real, {PyCompilerFlags*}], PyObject) +def PyRun_FileExFlags(space, fp, filename, start, globals, locals, closeit, flags): + """Similar to PyRun_StringFlags(), but the Python source code is read from + fp instead of an in-memory string. filename should be the name of the file. + If closeit is true, the file is closed before PyRun_FileExFlags() + returns.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real], PyObject) +def Py_CompileString(space, str, filename, start): + """This is a simplified interface to Py_CompileStringFlags() below, leaving + flags set to NULL.""" + raise NotImplementedError + + at cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, {PyCompilerFlags*}], PyObject) +def Py_CompileStringFlags(space, str, filename, start, flags): + """Parse and compile the Python source code in str, returning the resulting code + object. The start token is given by start; this can be used to constrain the + code which can be compiled and should be Py_eval_input, + Py_file_input, or Py_single_input. The filename specified by + filename is used to construct the code object and may appear in tracebacks or + SyntaxError exception messages. This returns NULL if the code cannot + be parsed or compiled.""" + raise NotImplementedError + + at cpython_api([{PyCodeObject*}, PyObject, PyObject], PyObject) +def PyEval_EvalCode(space, co, globals, locals): + """This is a simplified interface to PyEval_EvalCodeEx(), with just + the code object, and the dictionaries of global and local variables. + The other arguments are set to NULL.""" + raise NotImplementedError + + at cpython_api([{PyCodeObject*}, PyObject, PyObject, {PyObject**}, rffi.INT_real, {PyObject**}, rffi.INT_real, {PyObject**}, rffi.INT_real, PyObject], PyObject) +def PyEval_EvalCodeEx(space, co, globals, locals, args, argcount, kws, kwcount, defs, defcount, closure): + """Evaluate a precompiled code object, given a particular environment for its + evaluation. This environment consists of dictionaries of global and local + variables, arrays of arguments, keywords and defaults, and a closure tuple of + cells.""" + raise NotImplementedError + + at cpython_api([{PyFrameObject*}], PyObject) +def PyEval_EvalFrame(space, f): + """Evaluate an execution frame. This is a simplified interface to + PyEval_EvalFrameEx, for backward compatibility.""" + raise NotImplementedError + + at cpython_api([{PyFrameObject*}, rffi.INT_real], PyObject) +def PyEval_EvalFrameEx(space, f, throwflag): + """This is the main, unvarnished function of Python interpretation. It is + literally 2000 lines long. The code object associated with the execution + frame f is executed, interpreting bytecode and executing calls as needed. + The additional throwflag parameter can mostly be ignored - if true, then + it causes an exception to immediately be thrown; this is used for the + throw() methods of generator objects.""" + raise NotImplementedError + + at cpython_api([{PyCompilerFlags*}], rffi.INT_real) +def PyEval_MergeCompilerFlags(space, cf): + """This function changes the flags of the current evaluation frame, and returns + true on success, false on failure.""" + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyWeakref_Check(space, ): + """Return true if ob is either a reference or proxy object. + """ + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyWeakref_CheckRef(space, ): + """Return true if ob is a reference object. + """ + raise NotImplementedError + + at cpython_api([{ob}], rffi.INT_real) +def PyWeakref_CheckProxy(space, ): + """Return true if ob is a proxy object. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyWeakref_NewRef(space, ob, callback): + """Return a weak reference object for the object ob. This will always return + a new reference, but is not guaranteed to create a new object; an existing + reference object may be returned. The second parameter, callback, can be a + callable object that receives notification when ob is garbage collected; it + should accept a single parameter, which will be the weak reference object + itself. callback may also be None or NULL. If ob is not a + weakly-referencable object, or if callback is not callable, None, or + NULL, this will return NULL and raise TypeError. + """ + raise NotImplementedError + + at cpython_api([PyObject, PyObject], PyObject) +def PyWeakref_NewProxy(space, ob, callback): + """Return a weak reference proxy object for the object ob. This will always + return a new reference, but is not guaranteed to create a new object; an + existing proxy object may be returned. The second parameter, callback, can + be a callable object that receives notification when ob is garbage + collected; it should accept a single parameter, which will be the weak + reference object itself. callback may also be None or NULL. If ob + is not a weakly-referencable object, or if callback is not callable, + None, or NULL, this will return NULL and raise TypeError. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyWeakref_GetObject(space, ref): + """Return the referenced object from a weak reference, ref. If the referent is + no longer live, returns None. + """ + raise NotImplementedError + + at cpython_api([PyObject], PyObject, borrowed=True) +def PyWeakref_GET_OBJECT(space, ref): + """Similar to PyWeakref_GetObject(), but implemented as a macro that does no + error checking. + """ + raise NotImplementedError From fijal at codespeak.net Sat Mar 27 00:58:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 00:58:33 +0100 (CET) Subject: [pypy-svn] r72934 - in pypy/branch/blackhole-improvement/pypy/tool/algo: . test Message-ID: <20100326235833.6ADC1282B9C@codespeak.net> Author: fijal Date: Sat Mar 27 00:58:31 2010 New Revision: 72934 Added: pypy/branch/blackhole-improvement/pypy/tool/algo/color.py (contents, props changed) pypy/branch/blackhole-improvement/pypy/tool/algo/test/test_color.py (contents, props changed) Log: Start writing graph coloring algorithm. Not much so far, that was arguably not a very productive day. Added: pypy/branch/blackhole-improvement/pypy/tool/algo/color.py ============================================================================== --- (empty file) +++ pypy/branch/blackhole-improvement/pypy/tool/algo/color.py Sat Mar 27 00:58:31 2010 @@ -0,0 +1,7 @@ + +class DependencyGraph(object): + """ A dependency graph for a given control flow graph (CFG). + + Each variable is an node in a graph and we have an edge + if two variables are alive at the same point of time + """ Added: pypy/branch/blackhole-improvement/pypy/tool/algo/test/test_color.py ============================================================================== --- (empty file) +++ pypy/branch/blackhole-improvement/pypy/tool/algo/test/test_color.py Sat Mar 27 00:58:31 2010 @@ -0,0 +1,16 @@ + +from pypy.translator.translator import graphof +from pypy.annotation.annrpython import RPythonAnnotator +from pypy.tool.algo.color import DependencyGraph + +def test_one(): + def f(a, b, c): + d = a + b + e = b + c + f = d + e + return d + e + f + + a = RPythonAnnotator() + a.build_types(f, [int, int, int]) + graph = graphof(a.translator, f) + dep_graph = DependencyGraph(graph) From fijal at codespeak.net Sat Mar 27 00:59:55 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 00:59:55 +0100 (CET) Subject: [pypy-svn] r72935 - pypy/branch/blackhole-improvement/pypy/tool/algo Message-ID: <20100326235955.01D29282B9C@codespeak.net> Author: fijal Date: Sat Mar 27 00:59:54 2010 New Revision: 72935 Modified: pypy/branch/blackhole-improvement/pypy/tool/algo/color.py Log: Mention a paper which describes SSA-based efficient graph coloring Modified: pypy/branch/blackhole-improvement/pypy/tool/algo/color.py ============================================================================== --- pypy/branch/blackhole-improvement/pypy/tool/algo/color.py (original) +++ pypy/branch/blackhole-improvement/pypy/tool/algo/color.py Sat Mar 27 00:59:54 2010 @@ -4,4 +4,7 @@ Each variable is an node in a graph and we have an edge if two variables are alive at the same point of time + + the whole algorithm is based on the following paper: + http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.86.1578&rep=rep1&type=pdf """ From xoraxax at codespeak.net Sat Mar 27 02:45:34 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 02:45:34 +0100 (CET) Subject: [pypy-svn] r72936 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327014534.B320E282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 02:45:33 2010 New Revision: 72936 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Add comments about missing code, set _HEAPTYPE. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 02:45:33 2010 @@ -6,7 +6,7 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable -from pypy.objspace.std.typeobject import W_TypeObject +from pypy.objspace.std.typeobject import W_TypeObject, _HEAPTYPE from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ @@ -202,8 +202,10 @@ dict_w = {} convert_method_defs(space, dict_w, pto.c_tp_methods, pto) convert_getset_defs(space, dict_w, pto.c_tp_getset, pto) + # XXX missing: convert_member_defs W_TypeObject.__init__(self, space, rffi.charp2str(pto.c_tp_name), bases_w or [space.w_object], dict_w) + self.__flags__ = _HEAPTYPE class W_PyCObject(Wrappable): def __init__(self, space): @@ -256,9 +258,7 @@ base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) Py_XDECREF(space, base_pyo) Py_XDECREF(space, obj_pto.c_tp_bases) - # XXX XDECREF tp_dict, tp_mro, tp_cache, - # tp_subclasses - # free tp_doc + Py_XDECREF(space, obj_pto.c_tp_cache) # lets do it like cpython if obj_pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: lltype.free(obj_pto.c_tp_name, flavor="raw") obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) @@ -293,6 +293,11 @@ pto.c_tp_free = PyObject_Del.api_func.get_llhelper(space) pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out + pto.c_tp_itemsize = 0 + # uninitialized fields: + # c_tp_print, c_tp_getattr, c_tp_setattr + # XXX implement + # c_tp_compare and the following fields (see http://docs.python.org/c-api/typeobj.html ) bases_w = w_type.bases_w assert len(bases_w) <= 1 pto.c_tp_base = lltype.nullptr(PyTypeObject) @@ -308,6 +313,7 @@ pto.c_obj_type = lltype.nullptr(PyObject.TO) # XXX fill slots in pto + # would look like fixup_slot_dispatchers() return pto @cpython_api([PyTypeObjectPtr], rffi.INT_real, error=-1) @@ -339,6 +345,11 @@ pto.c_tp_bases = make_ref(space, bases) if w_obj is None: PyPyType_Register(space, pto) + # missing: + # inherit_special, inherit_slots, setting __doc__ if not defined and tp_doc defined + # inheriting tp_as_* slots + # unsupported: + # tp_mro, tp_subclasses finally: pto.c_tp_flags &= ~Py_TPFLAGS_READYING pto.c_tp_flags = (pto.c_tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY From xoraxax at codespeak.net Sat Mar 27 02:51:04 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 02:51:04 +0100 (CET) Subject: [pypy-svn] r72937 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327015104.A31A8282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 02:51:03 2010 New Revision: 72937 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Oops, should have run tests (which were segfaulting :)). Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 02:51:03 2010 @@ -294,6 +294,7 @@ pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out pto.c_tp_itemsize = 0 + pto.c_tp_cache = lltype.nullptr(PyObject.TO) # uninitialized fields: # c_tp_print, c_tp_getattr, c_tp_setattr # XXX implement From xoraxax at codespeak.net Sat Mar 27 02:55:58 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 02:55:58 +0100 (CET) Subject: [pypy-svn] r72938 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327015558.527A6282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 02:55:56 2010 New Revision: 72938 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Better way to fix the segfaults ... Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 02:55:56 2010 @@ -254,11 +254,11 @@ # Py_INCREF(space, pto) basicsize = pto._obj.c_tp_basicsize T = get_padded_type(PyObject.TO, basicsize) - py_obj = lltype.malloc(T, None, flavor="raw") + py_obj = lltype.malloc(T, None, flavor="raw", zero=True) py_obj.c_obj_refcnt = 1 py_obj.c_obj_type = rffi.cast(PyObject, pto) elif isinstance(w_obj, W_StringObject): - py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw') + py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw', zero=True) py_obj.c_size = len(space.str_w(w_obj)) py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) @@ -266,7 +266,7 @@ py_obj.c_obj_refcnt = 1 py_obj.c_obj_type = rffi.cast(PyObject, pto) else: - py_obj = lltype.malloc(PyObject.TO, None, flavor="raw") + py_obj = lltype.malloc(PyObject.TO, None, flavor="raw", zero=True) py_obj.c_obj_refcnt = 1 pto = make_ref(space, space.type(w_obj)) py_obj.c_obj_type = rffi.cast(PyObject, pto) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 02:55:56 2010 @@ -274,7 +274,7 @@ assert not isinstance(w_type, W_PyCTypeObject) assert isinstance(w_type, W_TypeObject) - pto = lltype.malloc(PyTypeObject, None, flavor="raw") + pto = lltype.malloc(PyTypeObject, None, flavor="raw", zero=True) pto.c_obj_refcnt = 1 # put the type object early into the dict # to support dependency cycles like object/type @@ -294,7 +294,6 @@ pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out pto.c_tp_itemsize = 0 - pto.c_tp_cache = lltype.nullptr(PyObject.TO) # uninitialized fields: # c_tp_print, c_tp_getattr, c_tp_setattr # XXX implement From xoraxax at codespeak.net Sat Mar 27 03:15:43 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 03:15:43 +0100 (CET) Subject: [pypy-svn] r72939 - in pypy/branch/cpython-extension/pypy: module/cpyext objspace/std translator/goal Message-ID: <20100327021543.3986E282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 03:15:41 2010 New Revision: 72939 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py pypy/branch/cpython-extension/pypy/translator/goal/ann_override.py Log: Use an own flag for us. This is important because we proxy non-heap types in fact but we do not want the optimization of the lookup caches. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 03:15:41 2010 @@ -6,7 +6,7 @@ from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.baseobjspace import Wrappable -from pypy.objspace.std.typeobject import W_TypeObject, _HEAPTYPE +from pypy.objspace.std.typeobject import W_TypeObject, _CPYTYPE from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ @@ -203,26 +203,20 @@ convert_method_defs(space, dict_w, pto.c_tp_methods, pto) convert_getset_defs(space, dict_w, pto.c_tp_getset, pto) # XXX missing: convert_member_defs - W_TypeObject.__init__(self, space, rffi.charp2str(pto.c_tp_name), + full_name = rffi.charp2str(pto.c_tp_name) + module_name, extension_name = full_name.split(".", 1) + dict_w["__module__"] = space.wrap(module_name) + W_TypeObject.__init__(self, space, extension_name, bases_w or [space.w_object], dict_w) - self.__flags__ = _HEAPTYPE + self.__flags__ = _CPYTYPE class W_PyCObject(Wrappable): def __init__(self, space): self.space = space -# def __del__(self): -# space = self.space -# self.clear_all_weakrefs() -# w_type = space.type(self) -# assert isinstance(w_type, W_PyCTypeObject) -# pto = w_type.pto -# generic_cpy_call(space, pto.c_tp_dealloc, self) - @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): - print >>sys.stderr, "Dealloc of", obj pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto Modified: pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py Sat Mar 27 03:15:41 2010 @@ -13,6 +13,7 @@ from pypy.rlib.rarithmetic import intmask, r_uint from copy_reg import _HEAPTYPE +_CPYTYPE = 1 # used for non-heap types defined in C # from compiler/misc.py @@ -82,7 +83,7 @@ w_self.needsdel = False w_self.weakrefable = False w_self.weak_subclasses = [] - w_self.__flags__ = 0 # or _HEAPTYPE + w_self.__flags__ = 0 # or _HEAPTYPE or _CPYTYPE w_self.instancetypedef = overridetypedef if overridetypedef is not None: @@ -334,6 +335,9 @@ def is_heaptype(w_self): return w_self.__flags__&_HEAPTYPE + def is_cpytype(w_self): + return w_self.__flags__ & _CPYTYPE + def get_module(w_self): space = w_self.space if w_self.is_heaptype() and '__module__' in w_self.dict_w: Modified: pypy/branch/cpython-extension/pypy/translator/goal/ann_override.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/goal/ann_override.py (original) +++ pypy/branch/cpython-extension/pypy/translator/goal/ann_override.py Sat Mar 27 03:15:41 2010 @@ -81,7 +81,7 @@ def attach_lookup(pol, t, attr): cached = "cached_%s" % attr - if not t.is_heaptype(): + if not t.is_heaptype() and not t.is_cpytype(): pol._remember_immutable(t, cached) setattr(t, cached, t._lookup(attr)) return True @@ -89,7 +89,7 @@ def attach_lookup_in_type_where(pol, t, attr): cached = "cached_where_%s" % attr - if not t.is_heaptype(): + if not t.is_heaptype() and not t.is_cpytype(): pol._remember_immutable(t, cached) setattr(t, cached, t._lookup_where(attr)) return True @@ -177,14 +177,14 @@ CACHED_LOOKUP = """ def lookup_%(attr)s(space, w_obj, name): w_type = space.type(w_obj) - if not w_type.is_heaptype(): + if not w_type.is_heaptype() and not w_type.is_cpytype(): return w_type.cached_%(attr)s return w_type.lookup("%(attr)s") """ CACHED_LOOKUP_IN_TYPE_WHERE = """ def lookup_in_type_where_%(attr)s(space, w_type, name): - if not w_type.is_heaptype(): + if not w_type.is_heaptype() and not w_type.is_cpytype(): return w_type.cached_where_%(attr)s return w_type.lookup_where("%(attr)s") """ From arigo at codespeak.net Sat Mar 27 11:19:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 11:19:43 +0100 (CET) Subject: [pypy-svn] r72940 - pypy/trunk/pypy/translator/platform/test Message-ID: <20100327101943.37920282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 11:19:41 2010 New Revision: 72940 Modified: pypy/trunk/pypy/translator/platform/test/test_maemo.py Log: Skip that test too. Modified: pypy/trunk/pypy/translator/platform/test/test_maemo.py ============================================================================== --- pypy/trunk/pypy/translator/platform/test/test_maemo.py (original) +++ pypy/trunk/pypy/translator/platform/test/test_maemo.py Sat Mar 27 11:19:41 2010 @@ -13,6 +13,7 @@ strict_on_stderr = False def setup_class(cls): + py.test.skip("TestMaemo: tests skipped for now") check_scratchbox() def test_includes_outside_scratchbox(self): From arigo at codespeak.net Sat Mar 27 11:22:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 11:22:11 +0100 (CET) Subject: [pypy-svn] r72941 - pypy/trunk/pypy/module/rctime/test Message-ID: <20100327102211.E524D282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 11:22:10 2010 New Revision: 72941 Modified: pypy/trunk/pypy/module/rctime/test/test_rctime.py Log: Argh, fix typo. Modified: pypy/trunk/pypy/module/rctime/test/test_rctime.py ============================================================================== --- pypy/trunk/pypy/module/rctime/test/test_rctime.py (original) +++ pypy/trunk/pypy/module/rctime/test/test_rctime.py Sat Mar 27 11:22:10 2010 @@ -226,7 +226,7 @@ tt = rctime.gmtime() result = rctime.strftime('%D', tt) if result != '': # else format not supported and we got '' - assert result == rctime.strftime('%m/%d/%y', t) + assert result == rctime.strftime('%m/%d/%y', tt) def test_strftime_bounds_checking(self): import time as rctime From arigo at codespeak.net Sat Mar 27 11:56:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 11:56:47 +0100 (CET) Subject: [pypy-svn] r72942 - pypy/branch/fix-win/pypy/translator/c/src Message-ID: <20100327105647.1E380282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 11:56:45 2010 New Revision: 72942 Modified: pypy/branch/fix-win/pypy/translator/c/src/commondefs.h Log: On Windows, define the Python.h-specific "MS_WINDOWS". Avoids issues when copying a bit of Python.h code; winstuff.c was never included :-( Modified: pypy/branch/fix-win/pypy/translator/c/src/commondefs.h ============================================================================== --- pypy/branch/fix-win/pypy/translator/c/src/commondefs.h (original) +++ pypy/branch/fix-win/pypy/translator/c/src/commondefs.h Sat Mar 27 11:56:45 2010 @@ -76,3 +76,7 @@ #define HAVE_LONG_LONG 1 #define Py_HUGE_VAL HUGE_VAL + +#ifdef _WIN32 +# define MS_WINDOWS /* a synonym */ +#endif From arigo at codespeak.net Sat Mar 27 12:14:50 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 12:14:50 +0100 (CET) Subject: [pypy-svn] r72943 - pypy/trunk/pypy/module/_file Message-ID: <20100327111450.39C78282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 12:14:48 2010 New Revision: 72943 Modified: pypy/trunk/pypy/module/_file/__init__.py Log: Ignore I/O errors when flush()ing streams when the process shuts down, instead of crashing with an RPython-level OSError. Modified: pypy/trunk/pypy/module/_file/__init__.py ============================================================================== --- pypy/trunk/pypy/module/_file/__init__.py (original) +++ pypy/trunk/pypy/module/_file/__init__.py Sat Mar 27 12:14:48 2010 @@ -24,8 +24,8 @@ MixedModule.__init__(self, space, *args) def shutdown(self, space): - # at shutdown, flush all open streams - from pypy.module._file.interp_file import getopenstreams + # at shutdown, flush all open streams. Ignore I/O errors. + from pypy.module._file.interp_file import getopenstreams, StreamErrors openstreams = getopenstreams(space) while openstreams: for stream in openstreams.keys(): @@ -34,7 +34,10 @@ except KeyError: pass # key was removed in the meantime else: - stream.flush() + try: + stream.flush() + except StreamErrors: + pass def setup_after_space_initialization(self): from pypy.module._file.interp_file import W_File From arigo at codespeak.net Sat Mar 27 12:18:03 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 12:18:03 +0100 (CET) Subject: [pypy-svn] r72944 - pypy/trunk/pypy/tool Message-ID: <20100327111803.4DD25282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 12:18:01 2010 New Revision: 72944 Modified: pypy/trunk/pypy/tool/runsubprocess.py Log: Don't try to run "python runsubprocess.pyc". It works on CPython, provided the .pyc file has the correct version (and crashes otherwise, instead of looking for the .py file). I suppose that "we don't support that" is good enough. Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Sat Mar 27 12:18:01 2010 @@ -42,8 +42,10 @@ if sys.platform != 'win32' and hasattr(os, 'fork'): # do this at import-time, when the process is still tiny + _source = os.path.dirname(os.path.abspath(__file__)) + _source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc' _child_stdin, _child_stdout = os.popen2( - "'%s' '%s'" % (sys.executable, os.path.abspath(__file__))) + "'%s' '%s'" % (sys.executable, _source)) def _run(*args): _child_stdin.write('%r\n' % (args,)) From arigo at codespeak.net Sat Mar 27 12:47:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 12:47:02 +0100 (CET) Subject: [pypy-svn] r72945 - pypy/trunk/pypy/jit/backend/x86/tool Message-ID: <20100327114702.672D5282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 12:47:00 2010 New Revision: 72945 Modified: pypy/trunk/pypy/jit/backend/x86/tool/viewcode.py Log: Use "-M intel". Thanks for jcreigh for pointing this out. Modified: pypy/trunk/pypy/jit/backend/x86/tool/viewcode.py ============================================================================== --- pypy/trunk/pypy/jit/backend/x86/tool/viewcode.py (original) +++ pypy/trunk/pypy/jit/backend/x86/tool/viewcode.py Sat Mar 27 12:47:00 2010 @@ -34,7 +34,8 @@ def machine_code_dump(data, originaddr): # the disassembler to use. 'objdump' writes GNU-style instructions. # 'ndisasm' would use Intel syntax, but you need to fix the output parsing. - objdump = 'objdump -b binary -m i386 --adjust-vma=%(origin)d -D %(file)s' + objdump = ('objdump -M intel -b binary -m i386 ' + '--adjust-vma=%(origin)d -D %(file)s') # f = open(tmpfile, 'wb') f.write(data) From arigo at codespeak.net Sat Mar 27 13:03:57 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 13:03:57 +0100 (CET) Subject: [pypy-svn] r72946 - in pypy/trunk/pypy: interpreter module/posix module/posix/test Message-ID: <20100327120357.B5507282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 13:03:55 2010 New Revision: 72946 Modified: pypy/trunk/pypy/interpreter/error.py pypy/trunk/pypy/module/posix/interp_posix.py pypy/trunk/pypy/module/posix/test/test_posix2.py Log: A function to raise OSError with the correct 'filename' attribute. Use it in os.stat() to test it. Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Sat Mar 27 13:03:55 2010 @@ -375,3 +375,10 @@ space.wrap(msg)) return OperationError(exc, w_error) wrap_oserror._annspecialcase_ = 'specialize:arg(2)' + +def wrap_oserror_filename(space, e, filename, exception_name='w_OSError'): + operr = wrap_oserror(space, e, exception_name) + space.setattr(operr.get_w_value(space), space.wrap('filename'), + space.wrap(filename)) + return operr +wrap_oserror_filename._annspecialcase_ = 'specialize:arg(2)' Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Sat Mar 27 13:03:55 2010 @@ -3,6 +3,7 @@ from pypy.rlib.rarithmetic import r_longlong from pypy.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, wrap_oserror +from pypy.interpreter.error import wrap_oserror_filename from pypy.rpython.module.ll_os import RegisterOs from pypy.rpython.module import ll_os_stat from pypy.rpython.lltypesystem import rffi, lltype @@ -177,7 +178,7 @@ try: st = os.stat(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) else: return build_stat_result(space, st) stat.unwrap_spec = [ObjSpace, str] Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sat Mar 27 13:03:55 2010 @@ -139,6 +139,7 @@ self.posix.stat("nonexistentdir/nonexistentfile") except OSError, e: assert e.errno == errno.ENOENT + assert e.filename == "nonexistentdir/nonexistentfile" # On Windows, when the parent directory does not exist, # the winerror is 3 (cannot find the path specified) # instead of 2 (cannot find the file specified) From arigo at codespeak.net Sat Mar 27 13:20:25 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 13:20:25 +0100 (CET) Subject: [pypy-svn] r72947 - pypy/trunk/pypy/module/zipimport Message-ID: <20100327122025.A1AF2282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 13:20:24 2010 New Revision: 72947 Modified: pypy/trunk/pypy/module/zipimport/interp_zipimport.py Log: Remove unused import. 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 Sat Mar 27 13:20:24 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module From arigo at codespeak.net Sat Mar 27 13:21:10 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 13:21:10 +0100 (CET) Subject: [pypy-svn] r72948 - in pypy/trunk/pypy/module/posix: . test Message-ID: <20100327122110.C3373282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 13:21:09 2010 New Revision: 72948 Modified: pypy/trunk/pypy/module/posix/interp_posix.py pypy/trunk/pypy/module/posix/test/test_posix2.py Log: Add the 'filename' attribute to all OSErrors where it makes sense. Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Sat Mar 27 13:21:09 2010 @@ -19,7 +19,7 @@ try: fd = os.open(fname, flag, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, fname) return space.wrap(fd) open.unwrap_spec = [ObjSpace, str, "c_int", "c_int"] @@ -188,7 +188,7 @@ try: st = os.lstat(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) else: return build_stat_result(space, st) lstat.unwrap_spec = [ObjSpace, str] @@ -245,7 +245,7 @@ try: ok = os.access(path, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, filename) else: return space.wrap(ok) access.unwrap_spec = [ObjSpace, str, "c_int"] @@ -284,7 +284,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) unlink.unwrap_spec = [ObjSpace, str] def remove(space, path): @@ -292,7 +292,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) remove.unwrap_spec = [ObjSpace, str] def _getfullpathname(space, path): @@ -301,7 +301,7 @@ try: fullpath = posix._getfullpathname(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) else: return space.wrap(fullpath) _getfullpathname.unwrap_spec = [ObjSpace, str] @@ -327,7 +327,7 @@ try: os.chdir(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) chdir.unwrap_spec = [ObjSpace, str] def mkdir(space, path, mode=0777): @@ -335,7 +335,7 @@ try: os.mkdir(path, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) mkdir.unwrap_spec = [ObjSpace, str, "c_int"] def rmdir(space, path): @@ -343,7 +343,7 @@ try: os.rmdir(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) rmdir.unwrap_spec = [ObjSpace, str] def strerror(space, errno): @@ -421,7 +421,7 @@ try: result = os.listdir(dirname) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, dirname) result_w = [space.wrap(s) for s in result] return space.newlist(result_w) listdir.unwrap_spec = [ObjSpace, str] @@ -440,7 +440,7 @@ try: os.chmod(path, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) chmod.unwrap_spec = [ObjSpace, str, "c_int"] def rename(space, old, new): @@ -502,12 +502,11 @@ try: result = os.readlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) return space.wrap(result) readlink.unwrap_spec = [ObjSpace, str] def fork(space): - try: pid = os.fork() except OSError, e: @@ -590,7 +589,7 @@ os.utime(path, None) return except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) try: msg = "utime() arg 2 must be a tuple (atime, mtime) or None" args_w = space.fixedview(w_tuple) @@ -600,7 +599,7 @@ modtime = space.float_w(args_w[1]) os.utime(path, (actime, modtime)) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) except OperationError, e: if not e.match(space, space.w_TypeError): raise @@ -696,7 +695,7 @@ try: os.chroot(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) return space.w_None chroot.unwrap_spec = [ObjSpace, str] @@ -865,7 +864,7 @@ try: os.chown(path, uid, gid) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror_filename(space, e, path) return space.w_None chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"] Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sat Mar 27 13:21:09 2010 @@ -133,19 +133,27 @@ assert st.st_mtime == 42.1 assert st.st_ctime == 43 + def test_stat_lstat(self): + import stat + st = self.posix.stat(".") + assert stat.S_ISDIR(st.st_mode) + st = self.posix.lstat(".") + assert stat.S_ISDIR(st.st_mode) + def test_stat_exception(self): import sys, errno - try: - self.posix.stat("nonexistentdir/nonexistentfile") - except OSError, e: - assert e.errno == errno.ENOENT - assert e.filename == "nonexistentdir/nonexistentfile" - # On Windows, when the parent directory does not exist, - # the winerror is 3 (cannot find the path specified) - # instead of 2 (cannot find the file specified) - if sys.platform == 'win32': - assert isinstance(e, WindowsError) - assert e.winerror == 3 + for fn in [self.posix.stat, self.posix.lstat]: + try: + fn("nonexistentdir/nonexistentfile") + except OSError, e: + assert e.errno == errno.ENOENT + assert e.filename == "nonexistentdir/nonexistentfile" + # On Windows, when the parent directory does not exist, + # the winerror is 3 (cannot find the path specified) + # instead of 2 (cannot find the file specified) + if sys.platform == 'win32': + assert isinstance(e, WindowsError) + assert e.winerror == 3 def test_pickle(self): import pickle, os @@ -161,11 +169,48 @@ posix = self.posix try: posix.open('qowieuqwoeiu', 0, 0) - except OSError: - pass + except OSError, e: + assert e.filename == 'qowieuqwoeiu' else: assert 0 + def test_filename_exception(self): + for fn in [self.posix.unlink, self.posix.remove, + self.posix.chdir, self.posix.mkdir, self.posix.rmdir, + self.posix.listdir, self.posix.readlink, + self.posix.chroot]: + try: + fn('qowieuqw/oeiu') + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_chmod_exception(self): + try: + self.posix.chmod('qowieuqw/oeiu', 0) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_chown_exception(self): + try: + self.posix.chown('qowieuqw/oeiu', 0, 0) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_utime_exception(self): + for arg in [None, (0, 0)]: + try: + self.posix.utime('qowieuqw/oeiu', arg) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + def test_functions_raise_error(self): def ex(func, *args): try: From arigo at codespeak.net Sat Mar 27 13:40:17 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 13:40:17 +0100 (CET) Subject: [pypy-svn] r72949 - pypy/trunk/pypy/interpreter Message-ID: <20100327124017.B2308282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 13:40:16 2010 New Revision: 72949 Modified: pypy/trunk/pypy/interpreter/error.py Log: Argh! Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Sat Mar 27 13:40:16 2010 @@ -381,4 +381,4 @@ space.setattr(operr.get_w_value(space), space.wrap('filename'), space.wrap(filename)) return operr -wrap_oserror_filename._annspecialcase_ = 'specialize:arg(2)' +wrap_oserror_filename._annspecialcase_ = 'specialize:arg(3)' From arigo at codespeak.net Sat Mar 27 13:49:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 13:49:21 +0100 (CET) Subject: [pypy-svn] r72950 - pypy/trunk/pypy/module/posix Message-ID: <20100327124921.28464282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 13:49:19 2010 New Revision: 72950 Modified: pypy/trunk/pypy/module/posix/interp_posix.py Log: Argh2! Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Sat Mar 27 13:49:19 2010 @@ -245,7 +245,7 @@ try: ok = os.access(path, mode) except OSError, e: - raise wrap_oserror_filename(space, e, filename) + raise wrap_oserror_filename(space, e, path) else: return space.wrap(ok) access.unwrap_spec = [ObjSpace, str, "c_int"] From arigo at codespeak.net Sat Mar 27 14:07:16 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 14:07:16 +0100 (CET) Subject: [pypy-svn] r72951 - pypy/branch/fix-win/pypy/lib/app_test/ctypes_tests Message-ID: <20100327130716.79D01282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 14:07:14 2010 New Revision: 72951 Modified: pypy/branch/fix-win/pypy/lib/app_test/ctypes_tests/test_funcptr.py Log: Skip this test for now. Fails on Windows when run on pypy-c -A. Modified: pypy/branch/fix-win/pypy/lib/app_test/ctypes_tests/test_funcptr.py ============================================================================== --- pypy/branch/fix-win/pypy/lib/app_test/ctypes_tests/test_funcptr.py (original) +++ pypy/branch/fix-win/pypy/lib/app_test/ctypes_tests/test_funcptr.py Sat Mar 27 14:07:14 2010 @@ -131,6 +131,8 @@ assert strtok(None, "\n") == None def test_from_address(self): + py.test.skip("This test needs mmap to make sure the" + " code is executable, please rewrite me") def make_function(): proto = CFUNCTYPE(c_int) a=create_string_buffer( From arigo at codespeak.net Sat Mar 27 16:28:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 16:28:11 +0100 (CET) Subject: [pypy-svn] r72952 - in pypy/trunk/pypy: interpreter/test lib/app_test/ctypes_tests module/posix/test module/zipimport module/zipimport/test translator/c/src Message-ID: <20100327152811.B0AFF282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 16:28:07 2010 New Revision: 72952 Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py pypy/trunk/pypy/interpreter/test/test_zpy.py pypy/trunk/pypy/lib/app_test/ctypes_tests/test_funcptr.py pypy/trunk/pypy/module/posix/test/test_posix2.py pypy/trunk/pypy/module/zipimport/interp_zipimport.py pypy/trunk/pypy/module/zipimport/test/test_zipimport.py pypy/trunk/pypy/translator/c/src/commondefs.h Log: Merge branch/fix-win. Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/test/test_executioncontext.py Sat Mar 27 16:28:07 2010 @@ -271,8 +271,8 @@ # would be called import os, sys print sys.executable, self.tmpfile - if sys.platform == "win32": # quote? what's that? - cmdformat = "%s %s" + if sys.platform == "win32": + cmdformat = '""%s" "%s""' # excellent! tons of "! else: cmdformat = "'%s' '%s'" g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r') Modified: pypy/trunk/pypy/interpreter/test/test_zpy.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_zpy.py (original) +++ pypy/trunk/pypy/interpreter/test/test_zpy.py Sat Mar 27 16:28:07 2010 @@ -6,17 +6,23 @@ pypypath = py.path.local(pypy.__file__).dirpath("bin", "py.py") +def cmdexec(s): + if sys.platform == 'win32': + s = '"%s"' % s # double double quotes + return py.process.cmdexec(s) + + def test_executable(): """Ensures sys.executable points to the py.py script""" # TODO : watch out for spaces/special chars in pypypath - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % - (sys.executable, pypypath) ) + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % + (sys.executable, pypypath) ) assert output.splitlines()[-1] == pypypath def test_special_names(): """Test the __name__ and __file__ special global names""" cmd = "print __name__; print '__file__' in globals()" - output = py.process.cmdexec( '''"%s" "%s" -c "%s" ''' % + output = cmdexec( '''"%s" "%s" -c "%s" ''' % (sys.executable, pypypath, cmd) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == 'False' @@ -26,7 +32,7 @@ tmpfile.write("print __name__; print __file__\n") tmpfile.close() - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == str(tmpfilepath) @@ -34,17 +40,17 @@ def test_argv_command(): """Some tests on argv""" # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c']) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) @@ -59,17 +65,17 @@ tmpfile.close() # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath]) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" "%s" hello''' % + output = cmdexec( '''"%s" "%s" "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O "%s" hello''' % + output = cmdexec( '''"%s" "%s" -O "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) @@ -94,7 +100,7 @@ e = None try: - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) except py.process.cmdexec.Error, e: pass Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_funcptr.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_funcptr.py (original) +++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_funcptr.py Sat Mar 27 16:28:07 2010 @@ -131,6 +131,8 @@ assert strtok(None, "\n") == None def test_from_address(self): + py.test.skip("This test needs mmap to make sure the" + " code is executable, please rewrite me") def make_function(): proto = CFUNCTYPE(c_int) a=create_string_buffer( Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/trunk/pypy/module/posix/test/test_posix2.py (original) +++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sat Mar 27 16:28:07 2010 @@ -355,7 +355,8 @@ os = self.posix for i in range(5): stream = os.popen('echo 1') - assert stream.read() == '1\n' + res = stream.read() + assert res == '1\n' stream.close() if hasattr(__import__(os.name), '_getfullpathname'): 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 Sat Mar 27 16:28:07 2010 @@ -131,7 +131,7 @@ def _find_relative_path(self, filename): if filename.startswith(self.filename): filename = filename[len(self.filename):] - if filename.startswith(os.sep): + if filename.startswith(os.path.sep) or filename.startswith(ZIPSEP): filename = filename[1:] if ZIPSEP != os.path.sep: filename = filename.replace(os.path.sep, ZIPSEP) @@ -361,7 +361,7 @@ "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] - if prefix.startswith(os.sep): + if prefix.startswith(os.path.sep) or prefix.startswith(ZIPSEP): prefix = prefix[1:] w_result = space.wrap(W_ZipImporter(space, name, filename, zip_file.NameToInfo, prefix)) 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 Sat Mar 27 16:28:07 2010 @@ -239,10 +239,11 @@ # value. Not sure why it doesn't the assertion uses import.archive # directly. -exarkun archive = importer.archive + realprefix = importer.prefix allbutlast = self.zipfile.split(os.path.sep)[:-1] prefix = 'directory' assert archive == self.zipfile - assert importer.prefix == prefix + assert realprefix == prefix def test_zip_directory_cache(self): """ Check full dictionary interface Modified: pypy/trunk/pypy/translator/c/src/commondefs.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/commondefs.h (original) +++ pypy/trunk/pypy/translator/c/src/commondefs.h Sat Mar 27 16:28:07 2010 @@ -76,3 +76,7 @@ #define HAVE_LONG_LONG 1 #define Py_HUGE_VAL HUGE_VAL + +#ifdef _WIN32 +# define MS_WINDOWS /* a synonym */ +#endif From arigo at codespeak.net Sat Mar 27 16:28:26 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 16:28:26 +0100 (CET) Subject: [pypy-svn] r72953 - pypy/branch/fix-win Message-ID: <20100327152826.149C9282B9D@codespeak.net> Author: arigo Date: Sat Mar 27 16:28:24 2010 New Revision: 72953 Removed: pypy/branch/fix-win/ Log: Remove merged branch. From arigo at codespeak.net Sat Mar 27 16:31:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 16:31:04 +0100 (CET) Subject: [pypy-svn] r72954 - pypy/build/bot2/pypybuildbot Message-ID: <20100327153104.977DE282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 16:31:03 2010 New Revision: 72954 Modified: pypy/build/bot2/pypybuildbot/master.py Log: Run nightly the {own64} tests too, as they are passing now. Modified: pypy/build/bot2/pypybuildbot/master.py ============================================================================== --- pypy/build/bot2/pypybuildbot/master.py (original) +++ pypy/build/bot2/pypybuildbot/master.py Sat Mar 27 16:31:03 2010 @@ -130,7 +130,7 @@ 'change_source': [], 'schedulers': [ - Nightly("nightly-first", [LINUX32], + Nightly("nightly-first", [LINUX32, LINUX64], hour=4, minute=44), Nightly("nightly", [APPLVLLINUX32, APPLVLWIN32, STACKLESSAPPLVLLINUX32, JITLINUX32, OJITLINUX32, From fijal at codespeak.net Sat Mar 27 16:42:16 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 16:42:16 +0100 (CET) Subject: [pypy-svn] r72955 - in pypy/trunk/pypy: interpreter module/mmap module/posix Message-ID: <20100327154216.01EDB282B9C@codespeak.net> Author: fijal Date: Sat Mar 27 16:42:15 2010 New Revision: 72955 Modified: pypy/trunk/pypy/interpreter/error.py pypy/trunk/pypy/module/mmap/interp_mmap.py pypy/trunk/pypy/module/posix/interp_posix.py Log: Simplify a bit error handling. Leverage the fact that OSError can accept filename as 3rd arg Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Sat Mar 27 16:42:15 2010 @@ -358,8 +358,8 @@ space.wrap(msg)) return OperationError(exc, w_error) -def wrap_oserror(space, e, exception_name='w_OSError'): - assert isinstance(e, OSError) +def wrap_oserror(space, e, filename=None, exception_name='w_OSError'): + assert isinstance(e, OSError) if _WINDOWS and isinstance(e, WindowsError): return wrap_windowserror(space, e) @@ -370,15 +370,10 @@ except ValueError: msg = 'error %d' % errno exc = getattr(space, exception_name) - w_error = space.call_function(exc, - space.wrap(errno), - space.wrap(msg)) + if filename is not None: + w_error = space.call_function(exc, space.wrap(errno), + space.wrap(msg), space.wrap(filename)) + else: + w_error = space.call_function(exc, space.wrap(errno), space.wrap(msg)) return OperationError(exc, w_error) -wrap_oserror._annspecialcase_ = 'specialize:arg(2)' - -def wrap_oserror_filename(space, e, filename, exception_name='w_OSError'): - operr = wrap_oserror(space, e, exception_name) - space.setattr(operr.get_w_value(space), space.wrap('filename'), - space.wrap(filename)) - return operr -wrap_oserror_filename._annspecialcase_ = 'specialize:arg(3)' +wrap_oserror._annspecialcase_ = 'specialize:arg(3)' Modified: pypy/trunk/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/trunk/pypy/module/mmap/interp_mmap.py (original) +++ pypy/trunk/pypy/module/mmap/interp_mmap.py Sat Mar 27 16:42:15 2010 @@ -57,7 +57,8 @@ try: return self.space.wrap(self.mmap.file_size()) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') descr_size.unwrap_spec = ['self'] def write(self, data): @@ -87,7 +88,8 @@ raise OperationError(self.space.w_ValueError, self.space.wrap(v.message)) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') flush.unwrap_spec = ['self', int, int] def move(self, dest, src, count): @@ -104,7 +106,8 @@ try: self.mmap.resize(newsize) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') resize.unwrap_spec = ['self', int] def __len__(self): @@ -224,7 +227,7 @@ return space.wrap(W_MMap(space, rmmap.mmap(fileno, length, flags, prot, access))) except OSError, e: - raise wrap_oserror(space, e, 'w_EnvironmentError') + raise wrap_oserror(space, e, exception_name='w_EnvironmentError') except RValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.message)) except RTypeError, e: @@ -238,7 +241,7 @@ return space.wrap(W_MMap(space, rmmap.mmap(fileno, length, tagname, access))) except OSError, e: - raise wrap_oserror(space, e, 'w_EnvironmentError') + raise wrap_oserror(space, e, exception_name='w_EnvironmentError') except RValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.message)) except RTypeError, e: Modified: pypy/trunk/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/trunk/pypy/module/posix/interp_posix.py (original) +++ pypy/trunk/pypy/module/posix/interp_posix.py Sat Mar 27 16:42:15 2010 @@ -3,7 +3,6 @@ from pypy.rlib.rarithmetic import r_longlong from pypy.rlib.unroll import unrolling_iterable from pypy.interpreter.error import OperationError, wrap_oserror -from pypy.interpreter.error import wrap_oserror_filename from pypy.rpython.module.ll_os import RegisterOs from pypy.rpython.module import ll_os_stat from pypy.rpython.lltypesystem import rffi, lltype @@ -19,7 +18,7 @@ try: fd = os.open(fname, flag, mode) except OSError, e: - raise wrap_oserror_filename(space, e, fname) + raise wrap_oserror(space, e, fname) return space.wrap(fd) open.unwrap_spec = [ObjSpace, str, "c_int", "c_int"] @@ -178,7 +177,7 @@ try: st = os.stat(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) else: return build_stat_result(space, st) stat.unwrap_spec = [ObjSpace, str] @@ -188,7 +187,7 @@ try: st = os.lstat(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) else: return build_stat_result(space, st) lstat.unwrap_spec = [ObjSpace, str] @@ -245,7 +244,7 @@ try: ok = os.access(path, mode) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) else: return space.wrap(ok) access.unwrap_spec = [ObjSpace, str, "c_int"] @@ -284,7 +283,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) unlink.unwrap_spec = [ObjSpace, str] def remove(space, path): @@ -292,7 +291,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) remove.unwrap_spec = [ObjSpace, str] def _getfullpathname(space, path): @@ -301,7 +300,7 @@ try: fullpath = posix._getfullpathname(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) else: return space.wrap(fullpath) _getfullpathname.unwrap_spec = [ObjSpace, str] @@ -327,7 +326,7 @@ try: os.chdir(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) chdir.unwrap_spec = [ObjSpace, str] def mkdir(space, path, mode=0777): @@ -335,7 +334,7 @@ try: os.mkdir(path, mode) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) mkdir.unwrap_spec = [ObjSpace, str, "c_int"] def rmdir(space, path): @@ -343,7 +342,7 @@ try: os.rmdir(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) rmdir.unwrap_spec = [ObjSpace, str] def strerror(space, errno): @@ -421,7 +420,7 @@ try: result = os.listdir(dirname) except OSError, e: - raise wrap_oserror_filename(space, e, dirname) + raise wrap_oserror(space, e, dirname) result_w = [space.wrap(s) for s in result] return space.newlist(result_w) listdir.unwrap_spec = [ObjSpace, str] @@ -440,7 +439,7 @@ try: os.chmod(path, mode) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) chmod.unwrap_spec = [ObjSpace, str, "c_int"] def rename(space, old, new): @@ -502,7 +501,7 @@ try: result = os.readlink(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) return space.wrap(result) readlink.unwrap_spec = [ObjSpace, str] @@ -589,7 +588,7 @@ os.utime(path, None) return except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) try: msg = "utime() arg 2 must be a tuple (atime, mtime) or None" args_w = space.fixedview(w_tuple) @@ -599,7 +598,7 @@ modtime = space.float_w(args_w[1]) os.utime(path, (actime, modtime)) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) except OperationError, e: if not e.match(space, space.w_TypeError): raise @@ -695,7 +694,7 @@ try: os.chroot(path) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) return space.w_None chroot.unwrap_spec = [ObjSpace, str] @@ -864,7 +863,7 @@ try: os.chown(path, uid, gid) except OSError, e: - raise wrap_oserror_filename(space, e, path) + raise wrap_oserror(space, e, path) return space.w_None chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"] From fijal at codespeak.net Sat Mar 27 16:47:59 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 16:47:59 +0100 (CET) Subject: [pypy-svn] r72956 - pypy/trunk/pypy/interpreter Message-ID: <20100327154759.31EBC282B9C@codespeak.net> Author: fijal Date: Sat Mar 27 16:47:57 2010 New Revision: 72956 Modified: pypy/trunk/pypy/interpreter/error.py Log: also try to handle windows error, sketchy, no tests on linux Modified: pypy/trunk/pypy/interpreter/error.py ============================================================================== --- pypy/trunk/pypy/interpreter/error.py (original) +++ pypy/trunk/pypy/interpreter/error.py Sat Mar 27 16:47:57 2010 @@ -344,7 +344,7 @@ else: _WINDOWS = True - def wrap_windowserror(space, e): + def wrap_windowserror(space, e, filename=None): from pypy.rlib import rwin32 winerror = e.winerror @@ -353,16 +353,19 @@ except ValueError: msg = 'Windows Error %d' % winerror exc = space.w_WindowsError - w_error = space.call_function(exc, - space.wrap(winerror), - space.wrap(msg)) + if filename is not None: + w_error = space.call_function(exc, space.wrap(winerror), + space.wrap(msg), space.wrap(filename)) + else: + w_error = space.call_function(exc, space.wrap(winerror), + space.wrap(msg)) return OperationError(exc, w_error) def wrap_oserror(space, e, filename=None, exception_name='w_OSError'): assert isinstance(e, OSError) if _WINDOWS and isinstance(e, WindowsError): - return wrap_windowserror(space, e) + return wrap_windowserror(space, e, filename) errno = e.errno try: From xoraxax at codespeak.net Sat Mar 27 17:03:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 17:03:13 +0100 (CET) Subject: [pypy-svn] r72957 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327160313.378AF282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 17:03:11 2010 New Revision: 72957 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Comment debug output. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sat Mar 27 17:03:11 2010 @@ -59,7 +59,7 @@ from pypy.module.cpyext.methodobject import generic_cpy_call pto = obj.c_obj_type pto = rffi.cast(PyTypeObjectPtr, pto) - print >>sys.stderr, "Calling dealloc slot of", obj, \ - "'s type which is", rffi.charp2str(pto.c_tp_name) + #print >>sys.stderr, "Calling dealloc slot of", obj, \ + # "'s type which is", rffi.charp2str(pto.c_tp_name) generic_cpy_call(space, pto.c_tp_dealloc, obj, decref_args=False) From xoraxax at codespeak.net Sat Mar 27 17:03:48 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 17:03:48 +0100 (CET) Subject: [pypy-svn] r72958 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327160348.1D6ED282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 17:03:46 2010 New Revision: 72958 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: Implement 2 tuple functions. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 17:03:46 2010 @@ -344,6 +344,10 @@ w_obj_type = space.type(w_obj) return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) +def general_check_exact(space, w_obj, w_type): + w_obj_type = space.type(w_obj) + return int(space.is_w(w_obj_type, w_type)) + # Make the wrapper for the cases (1) and (2) def make_wrapper(space, callable): def wrapper(*args): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Sat Mar 27 17:03:46 2010 @@ -1,6 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \ - general_check, CANNOT_FAIL, register_container + general_check, CANNOT_FAIL, register_container, \ + general_check_exact from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.tupleobject import W_TupleObject @@ -10,6 +11,11 @@ w_type = space.w_tuple return general_check(space, w_obj, w_type) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyTuple_CheckExact(space, w_obj): + w_type = space.w_tuple + return general_check_exact(space, w_obj, w_type) + @cpython_api([Py_ssize_t], PyObject) def PyTuple_New(space, size): return space.newtuple([space.w_None] * size) @@ -31,3 +37,11 @@ w_obj = w_t.wrappeditems[pos] register_container(space, w_t) return w_obj + + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def PyTuple_GET_SIZE(space, w_t): + """Return the size of the tuple p, which must be non-NULL and point to a tuple; + no error checking is performed. """ + assert isinstance(w_t, W_TupleObject) + return len(w_t.wrappeditems) + From xoraxax at codespeak.net Sat Mar 27 17:04:56 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 17:04:56 +0100 (CET) Subject: [pypy-svn] r72959 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327160456.32473282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 17:04:54 2010 New Revision: 72959 Added: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Implement slot wrappers, move code from typeobject.py to typeobjectdefs.py. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sat Mar 27 17:04:54 2010 @@ -2,6 +2,7 @@ from pypy.rlib.objectmodel import we_are_translated import pypy.module.cpyext.api from pypy.module.cpyext.state import State +from pypy.module.cpyext.slotdefs import init_slotdefs class Module(MixedModule): @@ -17,6 +18,7 @@ state = self.space.fromcache(State) if not we_are_translated(): state.api_lib = str(pypy.module.cpyext.api.build_bridge(self.space)) + state.slotdefs = init_slotdefs(self.space) else: XXX # build an import library when translating pypy. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Sat Mar 27 17:04:54 2010 @@ -43,6 +43,33 @@ return self.space.wrap(self.__repr__()) +class W_PyCWrapperObject(Wrappable): + def __init__(self, space, pto, method_name, wrapper_func, doc, flags, func): + self.space = space + self.method_name = method_name + self.wrapper_func = wrapper_func + self.doc = doc + self.flags = flags + self.func = func + assert flags == 0 + self.w_objclass = from_ref(space, pto) + + def call(self, w_self, w_args): + return generic_cpy_call(self.space, self.wrapper_func, w_self, w_args, self.func) + + + at unwrap_spec(ObjSpace, W_Root, Arguments) +def cwrapper_descr_call(space, w_self, __args__): + self = space.interp_w(W_PyCWrapperObject, w_self) + args_w, kw_w = __args__.unpack() + w_args = space.newtuple(args_w[1:]) + w_self = args_w[0] + if kw_w: + raise OperationError(space.w_TypeError, + space.wrap("keywords not yet supported")) + return self.call(w_self, w_args) + + @unwrap_spec(ObjSpace, W_Root, Arguments) def cfunction_descr_call(space, w_self, __args__): self = space.interp_w(W_PyCFunctionObject, w_self) @@ -51,7 +78,7 @@ if kw_w: raise OperationError(space.w_TypeError, space.wrap("keywords not yet supported")) - ret = self.call(None, space.newtuple(args_w)) + ret = self.call(None, w_args) return ret @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -80,7 +107,6 @@ 'builtin_function_or_method', __call__ = interp2app(cfunction_descr_call), ) - W_PyCFunctionObject.typedef.acceptable_as_base_class = False W_PyCMethodObject.typedef = TypeDef( @@ -91,13 +117,29 @@ __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCMethodObject), __repr__ = interp2app(W_PyCMethodObject.descr_method_repr), ) - W_PyCMethodObject.typedef.acceptable_as_base_class = False -def PyCFunction_NewEx(space, ml, w_self): # not directly the API sig + +W_PyCWrapperObject.typedef = TypeDef( + 'wrapper_descriptor', + __call__ = interp2app(cwrapper_descr_call), + __get__ = interp2app(cmethod_descr_get), + __name__ = interp_attrproperty('method_name', cls=W_PyCWrapperObject), + __doc__ = interp_attrproperty('doc', cls=W_PyCWrapperObject), + __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCWrapperObject), + # XXX missing: __getattribute__, __repr__ + ) +W_PyCWrapperObject.typedef.acceptable_as_base_class = False + + +def PyCFunction_NewEx(space, ml, w_self): # not exactly the API sig return space.wrap(W_PyCFunctionObject(space, ml, w_self)) def PyDescr_NewMethod(space, pto, method): return space.wrap(W_PyCMethodObject(space, method, pto)) +def PyDescr_NewWrapper(space, pto, method_name, wrapper_func, doc, flags, func): + # not exactly the API sig + return space.wrap(W_PyCWrapperObject(space, pto, method_name, + wrapper_func, doc, flags, func)) Added: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Sat Mar 27 17:04:54 2010 @@ -0,0 +1,306 @@ +import re + +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import generic_cpy_call, cpython_api, \ + PyObject +from pypy.module.cpyext.typeobjectdefs import unaryfunc, wrapperfunc +from pypy.module.cpyext.state import State +from pypy.interpreter.error import OperationError, operationerrfmt + +space = None + +def is_wrapper_func(func): + deco = cpython_api([PyObject, PyObject, rffi.VOIDP_real], PyObject, external=False) + return deco(func) + +def check_num_args(space, ob, n): + from pypy.module.cpyext.tupleobject import PyTuple_CheckExact, \ + PyTuple_GET_SIZE + if not PyTuple_CheckExact(space, ob): + raise OperationError(space.w_SystemError, + "PyArg_UnpackTuple() argument list is not a tuple") + if n == PyTuple_GET_SIZE(space, ob): + return + raise operationerrfmt(space.w_TypeError, + "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob)) + +def wrap_binaryfunc_l(space, w_self, w_args, func): + pass + +def wrap_binaryfunc_r(space, w_self, w_args, func): + pass + + at is_wrapper_func +def wrap_unaryfunc(space, w_self, w_args, func): + func_unary = rffi.cast(unaryfunc, func) + check_num_args(space, w_args, 0) + return generic_cpy_call(space, func_unary, w_self) + + +PyWrapperFlag_KEYWORDS = 1 + +# adopted from typeobject.c +def FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS): + wrapper = globals().get(WRAPPER, None) + if wrapper is not None: + wrapper = wrapper.api_func.get_llhelper(space) + else: + wrapper = lltype.nullptr(wrapperfunc.TO) + slotname = ("c_" + SLOT).split(".") + return (NAME, slotname, FUNCTION, wrapper, DOC, FLAGS) + +def TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, 0) + +ETSLOT = TPSLOT + +def SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return ETSLOT(NAME, "tp_as_sequence.c_" + SLOT, FUNCTION, WRAPPER, DOC) +def MPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return ETSLOT(NAME, "tp_as_mapping.c_" + SLOT, FUNCTION, WRAPPER, DOC) +def NBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, WRAPPER, DOC) +def UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, WRAPPER, + "x." + NAME + "() <==> " + DOC) +def IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, WRAPPER, + "x." + NAME + "(y) <==> x" + DOC + "y") +def BINSLOT(NAME, SLOT, FUNCTION, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \ + "x." + NAME + "(y) <==> x" + DOC + "y") +def RBINSLOT(NAME, SLOT, FUNCTION, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \ + "x." + NAME + "(y) <==> y" + DOC + "x") +def BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \ + "x." + NAME + "(y) <==> " + DOC) +def RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC): + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \ + "x." + NAME + "(y) <==> " + DOC) + +# TODO remove all casts +slotdef_replacements = ( + ("\s+", " "), + ("static [^{]*{", "("), + ("};", ")"), + (r"(?P +..SLOT\([^,]*, )(?P[^,]*), (?P[^,]*), (?P[^,]*)", r"\g'\g', '\g', '\g'"), + (r"(?P *R?[^ ]{3}SLOT(NOTINFIX)?\([^,]*, )(?P[^,]*), (?P[^,]*)", r"\g'\g', '\g'"), + ("'NULL'", "None"), + ("{NULL}", ""), + ("\),", "),\n"), + ) + +""" + /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. + The logic in abstract.c always falls back to nb_add/nb_multiply in + this case. Defining both the nb_* and the sq_* slots to call the + user-defined methods has unexpected side-effects, as shown by + test_descr.notimplemented() */ +""" +# Instructions for update: +# Copy new slotdefs from typeobject.c +# Remove comments +# Done +slotdefs = """ +static slotdef slotdefs[] = { + SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, + "x.__len__() <==> len(x)"), + SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + "x.__add__(y) <==> x+y"), + SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, + "x.__mul__(n) <==> x*n"), + SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, + "x.__rmul__(n) <==> n*x"), + SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, + "x.__getitem__(y) <==> x[y]"), + SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc, + "x.__getslice__(i, j) <==> x[i:j]\n\ + \n\ + Use of negative indices is not supported."), + SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, + "x.__setitem__(i, y) <==> x[i]=y"), + SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, + "x.__delitem__(y) <==> del x[y]"), + SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice, + wrap_ssizessizeobjargproc, + "x.__setslice__(i, j, y) <==> x[i:j]=y\n\ + \n\ + Use of negative indices is not supported."), + SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice, + "x.__delslice__(i, j) <==> del x[i:j]\n\ + \n\ + Use of negative indices is not supported."), + SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, + "x.__contains__(y) <==> y in x"), + SQSLOT("__iadd__", sq_inplace_concat, NULL, + wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), + SQSLOT("__imul__", sq_inplace_repeat, NULL, + wrap_indexargfunc, "x.__imul__(y) <==> x*=y"), + + MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, + "x.__len__() <==> len(x)"), + MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, + wrap_binaryfunc, + "x.__getitem__(y) <==> x[y]"), + MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, + wrap_objobjargproc, + "x.__setitem__(i, y) <==> x[i]=y"), + MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, + wrap_delitem, + "x.__delitem__(y) <==> del x[y]"), + + BINSLOT("__add__", nb_add, slot_nb_add, + "+"), + RBINSLOT("__radd__", nb_add, slot_nb_add, + "+"), + BINSLOT("__sub__", nb_subtract, slot_nb_subtract, + "-"), + RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, + "-"), + BINSLOT("__mul__", nb_multiply, slot_nb_multiply, + "*"), + RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, + "*"), + BINSLOT("__div__", nb_divide, slot_nb_divide, + "/"), + RBINSLOT("__rdiv__", nb_divide, slot_nb_divide, + "/"), + BINSLOT("__mod__", nb_remainder, slot_nb_remainder, + "%"), + RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, + "%"), + BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, + "divmod(x, y)"), + RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, + "divmod(y, x)"), + NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, + "x.__pow__(y[, z]) <==> pow(x, y[, z])"), + NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, + "y.__rpow__(x[, z]) <==> pow(x, y[, z])"), + UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), + UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), + UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, + "abs(x)"), + UNSLOT("__nonzero__", nb_nonzero, slot_nb_nonzero, wrap_inquirypred, + "x != 0"), + UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), + BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), + RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), + BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), + RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), + BINSLOT("__and__", nb_and, slot_nb_and, "&"), + RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), + BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), + RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), + BINSLOT("__or__", nb_or, slot_nb_or, "|"), + RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), + NBSLOT("__coerce__", nb_coerce, slot_nb_coerce, wrap_coercefunc, + "x.__coerce__(y) <==> coerce(x, y)"), + UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + "int(x)"), + UNSLOT("__long__", nb_long, slot_nb_long, wrap_unaryfunc, + "long(x)"), + UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + "float(x)"), + UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, + "oct(x)"), + UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, + "hex(x)"), + NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + "x[y:z] <==> x[y.__index__():z.__index__()]"), + IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, + wrap_binaryfunc, "+"), + IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, + wrap_binaryfunc, "-"), + IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, + wrap_binaryfunc, "*"), + IBSLOT("__idiv__", nb_inplace_divide, slot_nb_inplace_divide, + wrap_binaryfunc, "/"), + IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, + wrap_binaryfunc, "%"), + IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, + wrap_binaryfunc, "**"), + IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, + wrap_binaryfunc, "<<"), + IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, + wrap_binaryfunc, ">>"), + IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, + wrap_binaryfunc, "&"), + IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, + wrap_binaryfunc, "^"), + IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, + wrap_binaryfunc, "|"), + BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), + RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), + BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), + RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), + IBSLOT("__ifloordiv__", nb_inplace_floor_divide, + slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"), + IBSLOT("__itruediv__", nb_inplace_true_divide, + slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), + + TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + "x.__str__() <==> str(x)"), + TPSLOT("__str__", tp_print, NULL, NULL, ""), + TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, + "x.__repr__() <==> repr(x)"), + TPSLOT("__repr__", tp_print, NULL, NULL, ""), + TPSLOT("__cmp__", tp_compare, _PyObject_SlotCompare, wrap_cmpfunc, + "x.__cmp__(y) <==> cmp(x,y)"), + TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, + "x.__hash__() <==> hash(x)"), + FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, + "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), + TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), + TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), + TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), + TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), + TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + "x.__setattr__('name', value) <==> x.name = value"), + TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + "x.__delattr__('name') <==> del x.name"), + TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), + TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + "x.__lt__(y) <==> x x<=y"), + TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, + "x.__eq__(y) <==> x==y"), + TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, + "x.__ne__(y) <==> x!=y"), + TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, + "x.__gt__(y) <==> x>y"), + TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, + "x.__ge__(y) <==> x>=y"), + TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, + "x.__iter__() <==> iter(x)"), + TPSLOT("next", tp_iternext, slot_tp_iternext, wrap_next, + "x.next() -> the next value, or raise StopIteration"), + TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, + "descr.__get__(obj[, type]) -> value"), + TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, + "descr.__set__(obj, value)"), + TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + wrap_descr_delete, "descr.__delete__(obj)"), + FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, + "x.__init__(...) initializes x; " + "see x.__class__.__doc__ for signature", + PyWrapperFlag_KEYWORDS), + TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), + TPSLOT("__del__", tp_del, slot_tp_del, NULL, ""), + {NULL} +}; +""" +for regex, repl in slotdef_replacements: + slotdefs = re.sub(regex, repl, slotdefs) +def init_slotdefs(space_): + global space + space = space_ + try: + return eval(slotdefs) + finally: + space = None + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Sat Mar 27 17:04:54 2010 @@ -66,6 +66,16 @@ {NULL} /* Sentinel */ }; +static PyObject * +foo_repr(PyObject *self) +{ + PyObject *format; + + format = PyString_FromString(""); + if (format == NULL) return NULL; + return format; +} + static PyTypeObject footype = { PyVarObject_HEAD_INIT(NULL, 0) @@ -78,7 +88,7 @@ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ - 0, /*tp_repr*/ + foo_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py Sat Mar 27 17:04:54 2010 @@ -19,3 +19,5 @@ assert not "im_func" in dir(module.fooType.copy) assert module.fooType.copy.__objclass__ is module.fooType assert "copy" in repr(module.fooType.copy) + assert repr(module.fooType) == "" + assert repr(obj2) == "" Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 17:04:54 2010 @@ -1,7 +1,6 @@ import sys from pypy.rpython.lltypesystem import rffi, lltype -from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void from pypy.rpython.annlowlevel import llhelper from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.gateway import interp2app, unwrap_spec @@ -12,149 +11,15 @@ from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ - PyStringObject, ADDR, from_ref + PyStringObject, ADDR, from_ref, generic_cpy_call from pypy.interpreter.module import Module -from pypy.module.cpyext.modsupport import PyMethodDef, convert_method_defs +from pypy.module.cpyext.modsupport import convert_method_defs from pypy.module.cpyext.state import State -from pypy.module.cpyext.methodobject import generic_cpy_call +from pypy.module.cpyext.methodobject import PyDescr_NewWrapper from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, Py_XDECREF - -PyTypeObject = lltype.ForwardReference() -PyTypeObjectPtr = lltype.Ptr(PyTypeObject) -PyCFunction = Ptr(FuncType([PyObject, PyObject], PyObject)) -P, FT, PyO = Ptr, FuncType, PyObject -PyOPtr = Ptr(lltype.Array(PyO, hints={'nolength': True})) - - -# XXX -PyNumberMethods = PySequenceMethods = PyMappingMethods = \ - PyBufferProcs = PyMemberDef = rffi.VOIDP.TO - -freefunc = P(FT([rffi.VOIDP_real], Void)) -destructor = P(FT([PyO], Void)) -printfunc = P(FT([PyO, rffi.VOIDP_real, rffi.INT_real], rffi.INT)) -getattrfunc = P(FT([PyO, rffi.CCHARP], PyO)) -getattrofunc = P(FT([PyO, PyO], PyO)) -setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT_real)) -setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) -cmpfunc = P(FT([PyO, PyO], rffi.INT_real)) -reprfunc = P(FT([PyO], PyO)) -hashfunc = P(FT([PyO], lltype.Signed)) -richcmpfunc = P(FT([PyO, PyO, rffi.INT_real], PyO)) -getiterfunc = P(FT([PyO], PyO)) -iternextfunc = P(FT([PyO], PyO)) -descrgetfunc = P(FT([PyO, PyO, PyO], PyO)) -descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) -initproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) -newfunc = P(FT([PyTypeObjectPtr, PyO, PyO], PyO)) -allocfunc = P(FT([PyTypeObjectPtr, Py_ssize_t], PyO)) -unaryfunc = P(FT([PyO], PyO)) -binaryfunc = P(FT([PyO, PyO], PyO)) -ternaryfunc = P(FT([PyO, PyO, PyO], PyO)) -inquiry = P(FT([PyO], rffi.INT_real)) -lenfunc = P(FT([PyO], Py_ssize_t)) -coercion = P(FT([PyOPtr, PyOPtr], rffi.INT_real)) -intargfunc = P(FT([PyO, rffi.INT_real], PyO)) -intintargfunc = P(FT([PyO, rffi.INT_real, rffi.INT], PyO)) -ssizeargfunc = P(FT([PyO, Py_ssize_t], PyO)) -ssizessizeargfunc = P(FT([PyO, Py_ssize_t, Py_ssize_t], PyO)) -intobjargproc = P(FT([PyO, rffi.INT_real, PyO], rffi.INT)) -intintobjargproc = P(FT([PyO, rffi.INT_real, rffi.INT, PyO], rffi.INT)) -ssizeobjargproc = P(FT([PyO, Py_ssize_t, PyO], rffi.INT_real)) -ssizessizeobjargproc = P(FT([PyO, Py_ssize_t, Py_ssize_t, PyO], rffi.INT_real)) -objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) - -objobjproc = P(FT([PyO, PyO], rffi.INT_real)) -visitproc = P(FT([PyO, rffi.VOIDP_real], rffi.INT_real)) -traverseproc = P(FT([PyO, visitproc, rffi.VOIDP_real], rffi.INT_real)) - -getter = P(FT([PyO, rffi.VOIDP_real], PyO)) -setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real)) - -PyGetSetDef = cpython_struct("PyGetSetDef", ( - ("name", rffi.CCHARP), - ("get", getter), - ("set", setter), - ("doc", rffi.CCHARP), - ("closure", rffi.VOIDP_real), -)) - -PyTypeObjectFields = [] -PyTypeObjectFields.extend(PyVarObjectFields) -PyTypeObjectFields.extend([ - ("tp_name", rffi.CCHARP), # For printing, in format "." - ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation - - # Methods to implement standard operations - ("tp_dealloc", destructor), - ("tp_print", printfunc), - ("tp_getattr", getattrfunc), - ("tp_setattr", setattrfunc), - ("tp_compare", cmpfunc), - ("tp_repr", reprfunc), - - # Method suites for standard classes - ("tp_as_number", Ptr(PyNumberMethods)), - ("tp_as_sequence", Ptr(PySequenceMethods)), - ("tp_as_mapping", Ptr(PyMappingMethods)), - - # More standard operations (here for binary compatibility) - ("tp_hash", hashfunc), - ("tp_call", ternaryfunc), - ("tp_str", reprfunc), - ("tp_getattro", getattrofunc), - ("tp_setattro", setattrofunc), - - # Functions to access object as input/output buffer - ("tp_as_buffer", Ptr(PyBufferProcs)), - - # Flags to define presence of optional/expanded features - ("tp_flags", lltype.Signed), - - ("tp_doc", rffi.CCHARP), # Documentation string - - # Assigned meaning in release 2.0 - # call function for all accessible objects - ("tp_traverse", traverseproc), - - # delete references to contained objects - ("tp_clear", inquiry), - - # Assigned meaning in release 2.1 - # rich comparisons - ("tp_richcompare", richcmpfunc), - - # weak reference enabler - ("tp_weaklistoffset", Py_ssize_t), - - # Added in release 2.2 - # Iterators - ("tp_iter", getiterfunc), - ("tp_iternext", iternextfunc), - - # Attribute descriptor and subclassing stuff - ("tp_methods", Ptr(PyMethodDef)), - ("tp_members", Ptr(PyMemberDef)), - ("tp_getset", Ptr(PyGetSetDef)), - ("tp_base", Ptr(PyTypeObject)), - ("tp_dict", PyObject), - ("tp_descr_get", descrgetfunc), - ("tp_descr_set", descrsetfunc), - ("tp_dictoffset", Py_ssize_t), # can be ignored in PyPy - ("tp_init", initproc), - ("tp_alloc", allocfunc), - ("tp_new", newfunc), - ("tp_free", freefunc), # Low-level free-memory routine - ("tp_is_gc", inquiry), # For PyObject_IS_GC - ("tp_bases", PyObject), - ("tp_mro", PyObject), # method resolution order - ("tp_cache", PyObject), - ("tp_subclasses", PyObject), - ("tp_weaklist", PyObject), - ("tp_del", destructor), - ]) -cpython_struct("PyTypeObject", PyTypeObjectFields, PyTypeObject) - +from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \ + PyGetSetDef +from pypy.module.cpyext.slotdefs import slotdefs class W_GetSetPropertyEx(GetSetProperty): # XXX fix this to be rpython @@ -194,21 +59,46 @@ w_descr = PyDescr_NewGetSet(space, getset, pto) dict_w[name] = w_descr +def add_operators(space, dict_w, pto): + # XXX support PyObject_HashNotImplemented + state = space.fromcache(State) + for method_name, slot_name, _, wrapper_func, doc, flags in state.slotdefs: # XXX use UI + if method_name in dict_w or wrapper_func is None: + continue + # XXX is this rpython? + if len(slot_name) == 1: + func = getattr(pto, slot_name[0]) + else: + assert len(slot_name) == 2 + struct = getattr(pto, slot_name[0]) + if not struct: + continue + func = getattr(struct, slot_name[1]) + func_voidp = rffi.cast(rffi.VOIDP_real, func) + if not func: + continue + dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name, wrapper_func, + doc, flags, func_voidp) + class W_PyCTypeObject(W_TypeObject): def __init__(self, space, pto): self.pto = pto bases_w = [] dict_w = {} + + add_operators(space, dict_w, pto) convert_method_defs(space, dict_w, pto.c_tp_methods, pto) convert_getset_defs(space, dict_w, pto.c_tp_getset, pto) # XXX missing: convert_member_defs + full_name = rffi.charp2str(pto.c_tp_name) module_name, extension_name = full_name.split(".", 1) dict_w["__module__"] = space.wrap(module_name) + W_TypeObject.__init__(self, space, extension_name, bases_w or [space.w_object], dict_w) - self.__flags__ = _CPYTYPE + self.__flags__ = _CPYTYPE # mainly disables lookup optimizations class W_PyCObject(Wrappable): def __init__(self, space): Added: pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py Sat Mar 27 17:04:54 2010 @@ -0,0 +1,223 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void +from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ + PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ + Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ + PyStringObject, ADDR, from_ref +from pypy.module.cpyext.modsupport import PyMethodDef + + +PyTypeObject = lltype.ForwardReference() +PyTypeObjectPtr = lltype.Ptr(PyTypeObject) +PyCFunction = Ptr(FuncType([PyObject, PyObject], PyObject)) +P, FT, PyO = Ptr, FuncType, PyObject +PyOPtr = Ptr(lltype.Array(PyO, hints={'nolength': True})) + + +# XXX +PyBufferProcs = PyMemberDef = rffi.VOIDP.TO + +freefunc = P(FT([rffi.VOIDP_real], Void)) +destructor = P(FT([PyO], Void)) +printfunc = P(FT([PyO, rffi.VOIDP_real, rffi.INT_real], rffi.INT)) +getattrfunc = P(FT([PyO, rffi.CCHARP], PyO)) +getattrofunc = P(FT([PyO, PyO], PyO)) +setattrfunc = P(FT([PyO, rffi.CCHARP, PyO], rffi.INT_real)) +setattrofunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) +cmpfunc = P(FT([PyO, PyO], rffi.INT_real)) +reprfunc = P(FT([PyO], PyO)) +hashfunc = P(FT([PyO], lltype.Signed)) +richcmpfunc = P(FT([PyO, PyO, rffi.INT_real], PyO)) +getiterfunc = P(FT([PyO], PyO)) +iternextfunc = P(FT([PyO], PyO)) +descrgetfunc = P(FT([PyO, PyO, PyO], PyO)) +descrsetfunc = P(FT([PyO, PyO, PyO], rffi.INT_real)) +initproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) +newfunc = P(FT([PyTypeObjectPtr, PyO, PyO], PyO)) +allocfunc = P(FT([PyTypeObjectPtr, Py_ssize_t], PyO)) +unaryfunc = P(FT([PyO], PyO)) +binaryfunc = P(FT([PyO, PyO], PyO)) +ternaryfunc = P(FT([PyO, PyO, PyO], PyO)) +inquiry = P(FT([PyO], rffi.INT_real)) +lenfunc = P(FT([PyO], Py_ssize_t)) +coercion = P(FT([PyOPtr, PyOPtr], rffi.INT_real)) +intargfunc = P(FT([PyO, rffi.INT_real], PyO)) +intintargfunc = P(FT([PyO, rffi.INT_real, rffi.INT], PyO)) +ssizeargfunc = P(FT([PyO, Py_ssize_t], PyO)) +ssizessizeargfunc = P(FT([PyO, Py_ssize_t, Py_ssize_t], PyO)) +intobjargproc = P(FT([PyO, rffi.INT_real, PyO], rffi.INT)) +intintobjargproc = P(FT([PyO, rffi.INT_real, rffi.INT, PyO], rffi.INT)) +ssizeobjargproc = P(FT([PyO, Py_ssize_t, PyO], rffi.INT_real)) +ssizessizeobjargproc = P(FT([PyO, Py_ssize_t, Py_ssize_t, PyO], rffi.INT_real)) +objobjargproc = P(FT([PyO, PyO, PyO], rffi.INT_real)) + +objobjproc = P(FT([PyO, PyO], rffi.INT_real)) +visitproc = P(FT([PyO, rffi.VOIDP_real], rffi.INT_real)) +traverseproc = P(FT([PyO, visitproc, rffi.VOIDP_real], rffi.INT_real)) + +getter = P(FT([PyO, rffi.VOIDP_real], PyO)) +setter = P(FT([PyO, PyO, rffi.VOIDP_real], rffi.INT_real)) + +wrapperfunc = P(FT([PyO, PyO, rffi.VOIDP_real], PyO)) +wrapperfunc_kwds = P(FT([PyO, PyO, rffi.VOIDP_real, PyO], PyO)) + + +PyGetSetDef = cpython_struct("PyGetSetDef", ( + ("name", rffi.CCHARP), + ("get", getter), + ("set", setter), + ("doc", rffi.CCHARP), + ("closure", rffi.VOIDP_real), +)) + +PyNumberMethods = cpython_struct("PyNumberMethods", ( + ("nb_add", binaryfunc), + ("nb_subtract", binaryfunc), + ("nb_multiply", binaryfunc), + ("nb_divide", binaryfunc), + ("nb_remainder", binaryfunc), + ("nb_divmod", binaryfunc), + ("nb_power", ternaryfunc), + ("nb_negative", unaryfunc), + ("nb_positive", unaryfunc), + ("nb_absolute", unaryfunc), + ("nb_nonzero", inquiry), + ("nb_invert", unaryfunc), + ("nb_lshift", binaryfunc), + ("nb_rshift", binaryfunc), + ("nb_and", binaryfunc), + ("nb_xor", binaryfunc), + ("nb_or", binaryfunc), + ("nb_coerce", coercion), + ("nb_int", unaryfunc), + ("nb_long", unaryfunc), + ("nb_float", unaryfunc), + ("nb_oct", unaryfunc), + ("nb_hex", unaryfunc), + ("nb_inplace_add", binaryfunc), + ("nb_inplace_subtract", binaryfunc), + ("nb_inplace_multiply", binaryfunc), + ("nb_inplace_divide", binaryfunc), + ("nb_inplace_remainder", binaryfunc), + ("nb_inplace_power", ternaryfunc), + ("nb_inplace_lshift", binaryfunc), + ("nb_inplace_rshift", binaryfunc), + ("nb_inplace_and", binaryfunc), + ("nb_inplace_xor", binaryfunc), + ("nb_inplace_or", binaryfunc), + + ("nb_floor_divide", binaryfunc), + ("nb_true_divide", binaryfunc), + ("nb_inplace_floor_divide", binaryfunc), + ("nb_inplace_true_divide", binaryfunc), + + ("nb_index", unaryfunc), +)) + +PySequenceMethods = cpython_struct("PySequenceMethods", ( + ("sq_length", lenfunc), + ("sq_concat", binaryfunc), + ("sq_repeat", ssizeargfunc), + ("sq_item", ssizeargfunc), + ("sq_slice", ssizessizeargfunc), + ("sq_ass_item", ssizeobjargproc), + ("sq_ass_slice", ssizessizeobjargproc), + ("sq_contains", objobjproc), + ("sq_inplace_concat", binaryfunc), + ("sq_inplace_repeat", ssizeargfunc), +)) + +PyMappingMethods = cpython_struct("PyMappingMethods", ( + ("mp_length", lenfunc), + ("mp_subscript", binaryfunc), + ("mp_ass_subscript", objobjargproc), +)) + +""" +PyBufferProcs = cpython_struct("PyBufferProcs", ( + ("bf_getreadbuffer", readbufferproc), + ("bf_getwritebuffer", writebufferproc), + ("bf_getsegcount", segcountproc), + ("bf_getcharbuffer", charbufferproc), + ("bf_getbuffer", getbufferproc), + ("bf_releasebuffer", releasebufferproc), +)) +""" + +PyTypeObjectFields = [] +PyTypeObjectFields.extend(PyVarObjectFields) +PyTypeObjectFields.extend([ + ("tp_name", rffi.CCHARP), # For printing, in format "." + ("tp_basicsize", Py_ssize_t), ("tp_itemsize", Py_ssize_t), # For allocation + + # Methods to implement standard operations + ("tp_dealloc", destructor), + ("tp_print", printfunc), + ("tp_getattr", getattrfunc), + ("tp_setattr", setattrfunc), + ("tp_compare", cmpfunc), + ("tp_repr", reprfunc), + + # Method suites for standard classes + ("tp_as_number", Ptr(PyNumberMethods)), + ("tp_as_sequence", Ptr(PySequenceMethods)), + ("tp_as_mapping", Ptr(PyMappingMethods)), + + # More standard operations (here for binary compatibility) + ("tp_hash", hashfunc), + ("tp_call", ternaryfunc), + ("tp_str", reprfunc), + ("tp_getattro", getattrofunc), + ("tp_setattro", setattrofunc), + + # Functions to access object as input/output buffer + ("tp_as_buffer", Ptr(PyBufferProcs)), + + # Flags to define presence of optional/expanded features + ("tp_flags", lltype.Signed), + + ("tp_doc", rffi.CCHARP), # Documentation string + + # Assigned meaning in release 2.0 + # call function for all accessible objects + ("tp_traverse", traverseproc), + + # delete references to contained objects + ("tp_clear", inquiry), + + # Assigned meaning in release 2.1 + # rich comparisons + ("tp_richcompare", richcmpfunc), + + # weak reference enabler + ("tp_weaklistoffset", Py_ssize_t), + + # Added in release 2.2 + # Iterators + ("tp_iter", getiterfunc), + ("tp_iternext", iternextfunc), + + # Attribute descriptor and subclassing stuff + ("tp_methods", Ptr(PyMethodDef)), + ("tp_members", Ptr(PyMemberDef)), + ("tp_getset", Ptr(PyGetSetDef)), + ("tp_base", Ptr(PyTypeObject)), + ("tp_dict", PyObject), + ("tp_descr_get", descrgetfunc), + ("tp_descr_set", descrsetfunc), + ("tp_dictoffset", Py_ssize_t), # can be ignored in PyPy + ("tp_init", initproc), + ("tp_alloc", allocfunc), + ("tp_new", newfunc), + ("tp_free", freefunc), # Low-level free-memory routine + ("tp_is_gc", inquiry), # For PyObject_IS_GC + ("tp_bases", PyObject), + ("tp_mro", PyObject), # method resolution order + ("tp_cache", PyObject), + ("tp_subclasses", PyObject), + ("tp_weaklist", PyObject), + ("tp_del", destructor), + ]) +cpython_struct("PyTypeObject", PyTypeObjectFields, PyTypeObject) + + From arigo at codespeak.net Sat Mar 27 17:36:02 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 17:36:02 +0100 (CET) Subject: [pypy-svn] r72960 - pypy/branch/asmgcc-64 Message-ID: <20100327163602.5667C282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 17:36:00 2010 New Revision: 72960 Added: pypy/branch/asmgcc-64/ - copied from r72959, pypy/trunk/ Log: A branch in which to support asmgcc on x86-64. From arigo at codespeak.net Sat Mar 27 17:41:38 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 17:41:38 +0100 (CET) Subject: [pypy-svn] r72961 - pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform Message-ID: <20100327164138.BBB16282B9C@codespeak.net> Author: arigo Date: Sat Mar 27 17:41:37 2010 New Revision: 72961 Modified: pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py Log: Cast the result to INT. Modified: pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py Sat Mar 27 17:41:37 2010 @@ -412,11 +412,11 @@ key1 = addr1.address[0] key2 = addr2.address[0] if key1 < key2: - return -1 + return rffi.cast(rffi.INT, -1) elif key1 == key2: - return 0 + return rffi.cast(rffi.INT, 0) else: - return 1 + return rffi.cast(rffi.INT, 1) # ____________________________________________________________ From xoraxax at codespeak.net Sat Mar 27 19:34:12 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 19:34:12 +0100 (CET) Subject: [pypy-svn] r72963 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327183412.40588282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 19:34:10 2010 New Revision: 72963 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Remove debug comment. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 19:34:10 2010 @@ -325,7 +325,6 @@ container_ptr = rffi.cast(ADDR, container) assert not state.last_container, "Last container was not fetched" state.last_container = container_ptr - print "Setting last_container to", hex(container_ptr) def add_borrowed_object(space, obj): state = space.fromcache(State) From xoraxax at codespeak.net Sat Mar 27 19:34:28 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 19:34:28 +0100 (CET) Subject: [pypy-svn] r72964 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100327183428.B4A87282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 19:34:27 2010 New Revision: 72964 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Log: Add tp_call func. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Sat Mar 27 19:34:27 2010 @@ -76,6 +76,12 @@ return format; } +static PyObject * +foo_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + Py_INCREF(kwds); + return kwds; +} static PyTypeObject footype = { PyVarObject_HEAD_INIT(NULL, 0) @@ -93,7 +99,7 @@ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ - 0, /*tp_call*/ + foo_call, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ From xoraxax at codespeak.net Sat Mar 27 19:34:54 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 19:34:54 +0100 (CET) Subject: [pypy-svn] r72965 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327183454.D8A82282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 19:34:53 2010 New Revision: 72965 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Remove indirection via wrappers, rpythonize the interface a bit more, add support for kwargs in slot wrappers. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Sat Mar 27 19:34:53 2010 @@ -4,7 +4,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app, unwrap_spec -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import BuiltinFunction, Method from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import PyObject, from_ref, \ @@ -44,18 +44,25 @@ class W_PyCWrapperObject(Wrappable): - def __init__(self, space, pto, method_name, wrapper_func, doc, flags, func): + def __init__(self, space, pto, method_name, wrapper_func, wrapper_func_kwds, + doc, func): self.space = space self.method_name = method_name self.wrapper_func = wrapper_func + self.wrapper_func_kwds = wrapper_func_kwds self.doc = doc - self.flags = flags self.func = func - assert flags == 0 self.w_objclass = from_ref(space, pto) - def call(self, w_self, w_args): - return generic_cpy_call(self.space, self.wrapper_func, w_self, w_args, self.func) + def call(self, w_self, w_args, w_kw): + if self.wrapper_func is None: + assert self.wrapper_func_kwds is not None + return self.wrapper_func_kwds(self.space, w_self, w_args, self.func, w_kw) + if self.space.is_true(w_kw): + raise operationerrfmt(space.w_TypeError, + "wrapper %s doesn't take any keyword arguments", + self.method_name) + return self.wrapper_func(self.space, w_self, w_args, self.func) @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -64,10 +71,10 @@ args_w, kw_w = __args__.unpack() w_args = space.newtuple(args_w[1:]) w_self = args_w[0] - if kw_w: - raise OperationError(space.w_TypeError, - space.wrap("keywords not yet supported")) - return self.call(w_self, w_args) + w_kw = space.newdict() + for key, w_obj in kw_w.items(): + space.setitem(w_kw, space.wrap(key), w_obj) + return self.call(w_self, w_args, w_kw) @unwrap_spec(ObjSpace, W_Root, Arguments) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Sat Mar 27 19:34:53 2010 @@ -3,15 +3,13 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import generic_cpy_call, cpython_api, \ PyObject -from pypy.module.cpyext.typeobjectdefs import unaryfunc, wrapperfunc +from pypy.module.cpyext.typeobjectdefs import unaryfunc, wrapperfunc,\ + ternaryfunc from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError, operationerrfmt space = None -def is_wrapper_func(func): - deco = cpython_api([PyObject, PyObject, rffi.VOIDP_real], PyObject, external=False) - return deco(func) def check_num_args(space, ob, n): from pypy.module.cpyext.tupleobject import PyTuple_CheckExact, \ @@ -24,30 +22,30 @@ raise operationerrfmt(space.w_TypeError, "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob)) -def wrap_binaryfunc_l(space, w_self, w_args, func): - pass - -def wrap_binaryfunc_r(space, w_self, w_args, func): - pass - - at is_wrapper_func def wrap_unaryfunc(space, w_self, w_args, func): func_unary = rffi.cast(unaryfunc, func) check_num_args(space, w_args, 0) return generic_cpy_call(space, func_unary, w_self) +def wrap_call(space, w_self, w_args, func, w_kwds): + func_target = rffi.cast(ternaryfunc, func) + return generic_cpy_call(space, func_target, w_self, w_args, w_kwds) + PyWrapperFlag_KEYWORDS = 1 # adopted from typeobject.c def FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS): wrapper = globals().get(WRAPPER, None) - if wrapper is not None: - wrapper = wrapper.api_func.get_llhelper(space) - else: - wrapper = lltype.nullptr(wrapperfunc.TO) slotname = ("c_" + SLOT).split(".") - return (NAME, slotname, FUNCTION, wrapper, DOC, FLAGS) + assert FLAGS == 0 or FLAGS == PyWrapperFlag_KEYWORDS + if FLAGS: + wrapper1 = None + wrapper2 = wrapper + else: + wrapper1 = wrapper + wrapper2 = None + return (NAME, slotname, FUNCTION, wrapper1, wrapper2, DOC) def TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC): return FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, 0) @@ -67,19 +65,18 @@ return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, WRAPPER, "x." + NAME + "(y) <==> x" + DOC + "y") def BINSLOT(NAME, SLOT, FUNCTION, DOC): - return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \ + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_l", \ "x." + NAME + "(y) <==> x" + DOC + "y") def RBINSLOT(NAME, SLOT, FUNCTION, DOC): - return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \ + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_r", \ "x." + NAME + "(y) <==> y" + DOC + "x") def BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC): - return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_l, \ + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_l", \ "x." + NAME + "(y) <==> " + DOC) def RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC): - return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, wrap_binaryfunc_r, \ + return ETSLOT(NAME, "tp_as_number.c_" + SLOT, FUNCTION, "wrap_binaryfunc_r", \ "x." + NAME + "(y) <==> " + DOC) -# TODO remove all casts slotdef_replacements = ( ("\s+", " "), ("static [^{]*{", "("), @@ -88,6 +85,7 @@ (r"(?P *R?[^ ]{3}SLOT(NOTINFIX)?\([^,]*, )(?P[^,]*), (?P[^,]*)", r"\g'\g', '\g'"), ("'NULL'", "None"), ("{NULL}", ""), + ("\(wrapperfunc\)", ""), ("\),", "),\n"), ) @@ -101,7 +99,7 @@ # Instructions for update: # Copy new slotdefs from typeobject.c # Remove comments -# Done +# Done. slotdefs = """ static slotdef slotdefs[] = { SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, @@ -304,3 +302,5 @@ finally: space = None +if __name__ == "__main__": + print slotdefs Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py Sat Mar 27 19:34:53 2010 @@ -21,3 +21,5 @@ assert "copy" in repr(module.fooType.copy) assert repr(module.fooType) == "" assert repr(obj2) == "" + print module.fooType.__call__ + assert obj2(foo=1, bar=2) == dict(foo=1, bar=2) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 19:34:53 2010 @@ -62,8 +62,8 @@ def add_operators(space, dict_w, pto): # XXX support PyObject_HashNotImplemented state = space.fromcache(State) - for method_name, slot_name, _, wrapper_func, doc, flags in state.slotdefs: # XXX use UI - if method_name in dict_w or wrapper_func is None: + for method_name, slot_name, _, wrapper_func, wrapper_func_kwds, doc in state.slotdefs: # XXX use UI + if method_name in dict_w or (wrapper_func is None and wrapper_func_kwds is None): continue # XXX is this rpython? if len(slot_name) == 1: @@ -78,7 +78,7 @@ if not func: continue dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name, wrapper_func, - doc, flags, func_voidp) + wrapper_func_kwds, doc, func_voidp) class W_PyCTypeObject(W_TypeObject): From xoraxax at codespeak.net Sat Mar 27 20:07:55 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 20:07:55 +0100 (CET) Subject: [pypy-svn] r72966 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327190755.353DC282BF1@codespeak.net> Author: xoraxax Date: Sat Mar 27 20:07:53 2010 New Revision: 72966 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py Log: Implement and test __repr__ of slot wrapper objects. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Sat Mar 27 20:07:53 2010 @@ -37,7 +37,7 @@ self.w_objclass = from_ref(space, pto) def __repr__(self): - return "method %r of %r objects" % (self.name, self.w_objclass.getname(self.space, '?')) + return "" % (self.name, self.w_objclass.getname(self.space, '?')) def descr_method_repr(self): return self.space.wrap(self.__repr__()) @@ -64,6 +64,9 @@ self.method_name) return self.wrapper_func(self.space, w_self, w_args, self.func) + def descr_method_repr(self): + return self.space.wrap("" % (self.method_name, + self.w_objclass.getname(self.space, '?'))) @unwrap_spec(ObjSpace, W_Root, Arguments) def cwrapper_descr_call(space, w_self, __args__): @@ -134,6 +137,7 @@ __name__ = interp_attrproperty('method_name', cls=W_PyCWrapperObject), __doc__ = interp_attrproperty('doc', cls=W_PyCWrapperObject), __objclass__ = interp_attrproperty_w('w_objclass', cls=W_PyCWrapperObject), + __repr__ = interp2app(W_PyCWrapperObject.descr_method_repr), # XXX missing: __getattribute__, __repr__ ) W_PyCWrapperObject.typedef.acceptable_as_base_class = False Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_typeobject.py Sat Mar 27 20:07:53 2010 @@ -21,5 +21,5 @@ assert "copy" in repr(module.fooType.copy) assert repr(module.fooType) == "" assert repr(obj2) == "" - print module.fooType.__call__ + assert repr(module.fooType.__call__) == "" assert obj2(foo=1, bar=2) == dict(foo=1, bar=2) From arigo at codespeak.net Sat Mar 27 20:14:23 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 20:14:23 +0100 (CET) Subject: [pypy-svn] r72967 - pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform Message-ID: <20100327191423.85D63282BF1@codespeak.net> Author: arigo Date: Sat Mar 27 20:14:21 2010 New Revision: 72967 Modified: pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py Log: Make two cases, for x86 versus x86-64, in that module. Modified: pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/rpython/memory/gctransform/asmgcroot.py Sat Mar 27 20:14:21 2010 @@ -10,6 +10,8 @@ from pypy.rlib.debug import ll_assert import sys +X86_64 = sys.maxint > 2147483647 + # # This transformer avoids the use of a shadow stack in a completely @@ -216,16 +218,17 @@ # first word of the frame of 'caller' (see picture # below). # - # * Four "locations" that specify where the function saves - # each of the four callee-saved registers (%ebx, %esi, - # %edi, %ebp). + # * Four or six "locations" that specify where the function + # saves each of the callee-saved registers: + # on x86: %ebx, %esi, %edi, %ebp + # on x86_64: %rbp, %rbx, %r12, %r13, %r14, %r15 # # * The number of live GC roots around the call. # # * For each GC root, an integer that specify where the # GC pointer is stored. This is a "location" too. # - # XXX the details are completely specific to X86!!! + # XXX the details are completely specific to x86 or x86_64!!! # a picture of the stack may help: # ^ ^ ^ # | ... | to older frames @@ -451,8 +454,8 @@ # The special pypy_asm_stackwalk(), implemented directly in # assembler, fills information about the current stack top in an # ASM_FRAMEDATA array and invokes an RPython callback with it. -# An ASM_FRAMEDATA is an array of 5 values that describe everything -# we need to know about a stack frame: +# An ASM_FRAMEDATA is an array of 5 (or 7) values that describe +# everything we need to know about a stack frame: # # - the value that %ebx had when the current function started # - the value that %esi had when the current function started @@ -461,9 +464,16 @@ # - frame address (actually the addr of the retaddr of the current function; # that's the last word of the frame in memory) # -CALLEE_SAVED_REGS = 4 # there are 4 callee-saved registers -INDEX_OF_EBP = 3 -FRAME_PTR = CALLEE_SAVED_REGS # the frame is at index 4 in the array +# On x86_64, we have 6 callee-saved registers instead of 4, +# in the order %rbp, %rbx, %r12, %r13, %r14, %r15. +# +if X86_64: + CALLEE_SAVED_REGS = 6 # there are 6 callee-saved registers + INDEX_OF_EBP = 0 +else: + CALLEE_SAVED_REGS = 4 # there are 4 callee-saved registers + INDEX_OF_EBP = 3 +FRAME_PTR = CALLEE_SAVED_REGS # the frame is after the regs in the array ASM_CALLBACK_PTR = lltype.Ptr(lltype.FuncType([], lltype.Void)) From xoraxax at codespeak.net Sat Mar 27 20:14:51 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 20:14:51 +0100 (CET) Subject: [pypy-svn] r72968 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327191451.1F797282BF1@codespeak.net> Author: xoraxax Date: Sat Mar 27 20:14:49 2010 New Revision: 72968 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Correctly declare functions without arguments. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 20:14:49 2010 @@ -480,7 +480,7 @@ arg = db.gettype(argtype) arg = arg.replace('@', 'arg%d' % (i,)) args.append(arg) - args = ', '.join(args) + args = ', '.join(args) or "void" callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) header = "%s %s(%s)" % (restype, name, args) pypy_decls.append(header + ";") From arigo at codespeak.net Sat Mar 27 20:14:53 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 20:14:53 +0100 (CET) Subject: [pypy-svn] r72969 - in pypy/branch/asmgcc-64/pypy/translator/c/gcc: . test test/elf64 Message-ID: <20100327191453.0F9B0282BF1@codespeak.net> Author: arigo Date: Sat Mar 27 20:14:50 2010 New Revision: 72969 Added: pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/elf64/ pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/elf64/track_basic_rsp.s Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/conftest.py pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/test_trackgcroot.py pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Log: Start whacking. The first test passes. Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/conftest.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/conftest.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/conftest.py Sat Mar 27 20:14:50 2010 @@ -4,6 +4,6 @@ class Module(py.test.collect.Module): def collect(self): cpu = detect_cpu.autodetect() - if cpu != 'x86': - py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) + if cpu not in ('x86', 'x86_64'): + py.test.skip("c/gcc directory skipped: cpu is %r" % (cpu,)) return super(Module, self).collect() Added: pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/elf64/track_basic_rsp.s ============================================================================== --- (empty file) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/elf64/track_basic_rsp.s Sat Mar 27 20:14:50 2010 @@ -0,0 +1,38 @@ + .type main, @function +main: + call somewhere + ;; expected {(%rsp) | %rbp, %rbx, %r12, %r13, %r14, %r15 | } + + pushq %r13 + call somewhere + ;; expected {8(%rsp) | %rbp, %rbx, %r12, (%rsp), %r14, %r15 | } + + pushq %rbx + call somewhere + ;; expected {16(%rsp) | %rbp, (%rsp), %r12, 8(%rsp), %r14, %r15 | } + + pushq %r12 + call somewhere + ;; expected {24(%rsp) | %rbp, 8(%rsp), (%rsp), 16(%rsp), %r14, %r15 | } + + pushq %r15 + call somewhere + ;; expected {32(%rsp) | %rbp, 16(%rsp), 8(%rsp), 24(%rsp), %r14, (%rsp) | } + + pushq %rbp + call somewhere + ;; expected {40(%rsp) | (%rsp), 24(%rsp), 16(%rsp), 32(%rsp), %r14, 8(%rsp) | } + + pushq %r14 + call somewhere + ;; expected {48(%rsp) | 8(%rsp), 32(%rsp), 24(%rsp), 40(%rsp), (%rsp), 16(%rsp) | } + + popq %r14 + popq %rbp + popq %r15 + popq %r12 + popq %rbx + popq %r13 + ret + + .size main, .-main Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/test_trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/test_trackgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/test/test_trackgcroot.py Sat Mar 27 20:14:50 2010 @@ -10,6 +10,7 @@ from pypy.translator.c.gcc.trackgcroot import compress_callshape from pypy.translator.c.gcc.trackgcroot import decompress_callshape from pypy.translator.c.gcc.trackgcroot import PARSERS +from pypy.translator.c.gcc.trackgcroot import Elf64FunctionGcRootTracker from StringIO import StringIO this_dir = py.path.local(__file__).dirpath() @@ -39,6 +40,37 @@ LOC_EBP_PLUS+24, LOC_EBP_PLUS+28)) == expected +def test_format_location_64(): + cls64 = Elf64FunctionGcRootTracker + assert format_location(LOC_NOWHERE, cls=cls64) == '?' + assert format_location(LOC_REG | (1<<2), cls=cls64) == '%rbp' + assert format_location(LOC_REG | (2<<2), cls=cls64) == '%rbx' + assert format_location(LOC_REG | (3<<2), cls=cls64) == '%r12' + assert format_location(LOC_REG | (4<<2), cls=cls64) == '%r13' + assert format_location(LOC_REG | (5<<2), cls=cls64) == '%r14' + assert format_location(LOC_REG | (6<<2), cls=cls64) == '%r15' + assert format_location(LOC_EBP_PLUS + 0, cls=cls64) == '(%rbp)' + assert format_location(LOC_EBP_PLUS + 8, cls=cls64) == '8(%rbp)' + assert format_location(LOC_EBP_MINUS + 8, cls=cls64) == '-8(%rbp)' + assert format_location(LOC_ESP_PLUS + 0, cls=cls64) == '(%rsp)' + assert format_location(LOC_ESP_PLUS + 8, cls=cls64) == '8(%rsp)' + +def test_format_callshape_64(): + cls64 = Elf64FunctionGcRootTracker + expected = ('{8(%rbp) ' # position of the return address + '| 16(%rbp), 24(%rbp), 32(%rbp), 40(%rbp), ' # 6 saved regs + '48(%rbp), 56(%rbp) ' + '| 64(%rbp), 72(%rbp)}') # GC roots + assert format_callshape((LOC_EBP_PLUS+8, + LOC_EBP_PLUS+16, + LOC_EBP_PLUS+24, + LOC_EBP_PLUS+32, + LOC_EBP_PLUS+40, + LOC_EBP_PLUS+48, + LOC_EBP_PLUS+56, + LOC_EBP_PLUS+64, + LOC_EBP_PLUS+72), cls=cls64) == expected + def test_compress_callshape(): shape = (1, 127, 0x1234, 0x5678, 0x234567, 0x765432, 0x61626364, 0x41424344) @@ -108,7 +140,7 @@ def test_computegcmaptable(): tests = [] - for format in ('elf', 'darwin', 'msvc'): + for format in ('elf', 'darwin', 'msvc', 'elf64'): for path in this_dir.join(format).listdir("track*.s"): n = path.purebasename[5:] try: @@ -133,12 +165,13 @@ print path.dirpath().basename + '/' + path.basename lines = path.readlines() expectedlines = lines[:] - tracker = PARSERS[format].FunctionGcRootTracker(lines) + trackercls = PARSERS[format].FunctionGcRootTracker + tracker = trackercls(lines) table = tracker.computegcmaptable(verbose=sys.maxint) tabledict = {} seen = {} for entry in table: - print '%s: %s' % (entry[0], format_callshape(entry[1])) + print '%s: %s' % (entry[0], format_callshape(entry[1], cls=trackercls)) tabledict[entry[0]] = entry[1] # find the ";; expected" lines prevline = "" @@ -151,7 +184,7 @@ label = prevmatch.group(1) assert label in tabledict got = tabledict[label] - assert format_callshape(got) == expected + assert format_callshape(got, cls=trackercls) == expected seen[label] = True if format == 'msvc': expectedlines.insert(i-2, 'PUBLIC\t%s\n' % (label,)) Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Sat Mar 27 20:14:50 2010 @@ -17,6 +17,9 @@ class FunctionGcRootTracker(object): skip = 0 + WORD = 4 + BITS = 32 + SUFFIX = 'l' @classmethod def init_regexp(cls): @@ -187,15 +190,28 @@ del self.currentlineno - @classmethod - def find_missing_visit_method(cls, opname): - # only for operations that are no-ops as far as we are concerned + def find_missing_visit_method(self, opname): + # if opname ends with an 'l' (on 32-bit) or a 'q' (on 64-bit), + # try to find the method that ends with an 'X'. On Windows, + # where SUFFIX='', try to just append 'X'. + if opname.endswith(self.SUFFIX): + basename = opname[:len(opname)-len(self.SUFFIX)] + try: + method = getattr(self, 'visit_' + basename + 'X') + except AttributeError: + pass # not found + else: + setattr(self, 'visit_' + opname, method) + return + # not found. This is the case only for operations that are + # no-ops as far as we are concerned, but check if it is really + # in IGNORE_OPS_WITH_PREFIXES. prefix = opname - while prefix not in cls.IGNORE_OPS_WITH_PREFIXES: + while prefix not in self.IGNORE_OPS_WITH_PREFIXES: prefix = prefix[:-1] if not prefix: raise UnrecognizedOperation(opname) - setattr(cls, 'visit_' + opname, cls.visit_nop) + setattr(self, 'visit_' + opname, self.visit_nop) def list_collecting_call_insns(self): return [insn for insn in self.insns if isinstance(insn, InsnCall) @@ -206,7 +222,7 @@ # in the frame at this point. This doesn't count the return address # which is the word immediately following the frame in memory. # The 'framesize' is set to an odd value if it is only an estimate - # (see visit_andl()). + # (see visit_andX()). def walker(insn, size_delta): check = deltas.setdefault(insn, size_delta) @@ -399,7 +415,7 @@ visit_xorb = visit_nop visit_xorw = visit_nop - def visit_addl(self, line, sign=+1): + def visit_addX(self, line, sign=+1): match = self.r_binaryinsn.match(line) source = match.group("source") target = match.group("target") @@ -414,8 +430,8 @@ else: return [] - def visit_subl(self, line): - return self.visit_addl(line, sign=-1) + def visit_subX(self, line): + return self.visit_addX(line, sign=-1) def unary_insn(self, line): match = self.r_unaryinsn.match(line) @@ -438,16 +454,16 @@ else: return [] - visit_xorl = binary_insn # used in "xor reg, reg" to create a NULL GC ptr - visit_orl = binary_insn + visit_xorX = binary_insn # used in "xor reg, reg" to create a NULL GC ptr + visit_orX = binary_insn # The various cmov* operations for name in ''' e ne g ge l le a ae b be p np s ns o no '''.split(): locals()['visit_cmov' + name] = binary_insn - locals()['visit_cmov' + name + 'l'] = binary_insn + locals()['visit_cmov' + name + 'X'] = binary_insn - def visit_andl(self, line): + def visit_andX(self, line): match = self.r_binaryinsn.match(line) target = match.group("target") if target == self.ESP: @@ -459,9 +475,7 @@ else: return self.binary_insn(line) - visit_and = visit_andl - - def visit_leal(self, line): + def visit_leaX(self, line): match = self.r_binaryinsn.match(line) target = match.group("target") if target == self.ESP: @@ -473,7 +487,7 @@ raise UnrecognizedOperation('epilogue without prologue') ofs_from_ebp = int(match.group(1) or '0') assert ofs_from_ebp <= 0 - framesize = 4 - ofs_from_ebp + framesize = self.WORD - ofs_from_ebp else: match = self.r_localvar_esp.match(source) # leal 12(%esp), %esp @@ -498,7 +512,7 @@ else: return [] - def visit_movl(self, line): + def visit_movX(self, line): match = self.r_binaryinsn.match(line) source = match.group("source") target = match.group("target") @@ -512,20 +526,20 @@ # gcc -fno-unit-at-a-time. return self.insns_for_copy(source, target) - visit_mov = visit_movl - - def visit_pushl(self, line): + def visit_pushX(self, line): match = self.r_unaryinsn.match(line) source = match.group(1) - return [InsnStackAdjust(-4)] + self.insns_for_copy(source, self.TOP_OF_STACK) + return ([InsnStackAdjust(-self.WORD)] + + self.insns_for_copy(source, self.TOP_OF_STACK)) def visit_pushw(self, line): return [InsnStackAdjust(-2)] # rare but not impossible def _visit_pop(self, target): - return self.insns_for_copy(self.TOP_OF_STACK, target) + [InsnStackAdjust(+4)] + return (self.insns_for_copy(self.TOP_OF_STACK, target) + + [InsnStackAdjust(+self.WORD)]) - def visit_popl(self, line): + def visit_popX(self, line): match = self.r_unaryinsn.match(line) target = match.group(1) return self._visit_pop(target) @@ -660,7 +674,7 @@ visit_jc = conditional_jump visit_jnc = conditional_jump - def visit_xchgl(self, line): + def visit_xchgX(self, line): # only support the format used in VALGRIND_DISCARD_TRANSLATIONS # which is to use a marker no-op "xchgl %ebx, %ebx" match = self.r_binaryinsn.match(line) @@ -747,32 +761,10 @@ EBP = '%ebp' EAX = '%eax' CALLEE_SAVE_REGISTERS = ['%ebx', '%esi', '%edi', '%ebp'] - REG2LOC = dict((_reg, LOC_REG | ((_i+1)<<2)) - for _i, _reg in enumerate(CALLEE_SAVE_REGISTERS)) OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])' LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)' OFFSET_LABELS = 2**30 - TOP_OF_STACK = '0(%esp)' - - r_functionstart = re.compile(r"\t.type\s+"+LABEL+",\s*[@]function\s*$") - r_functionend = re.compile(r"\t.size\s+"+LABEL+",\s*[.]-"+LABEL+"\s*$") LOCALVAR = r"%eax|%edx|%ecx|%ebx|%esi|%edi|%ebp|\d*[(]%esp[)]" - LOCALVARFP = LOCALVAR + r"|-?\d*[(]%ebp[)]" - r_localvarnofp = re.compile(LOCALVAR) - r_localvarfp = re.compile(LOCALVARFP) - r_localvar_esp = re.compile(r"(\d*)[(]%esp[)]") - r_localvar_ebp = re.compile(r"(-?\d*)[(]%ebp[)]") - - r_rel_label = re.compile(r"(\d+):\s*$") - r_jump_rel_label = re.compile(r"\tj\w+\s+"+"(\d+)f"+"\s*$") - - r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+[*]("+OPERAND+")\s*$") - r_jmptable_item = re.compile(r"\t.long\t"+LABEL+"(-\"[A-Za-z0-9$]+\")?\s*$") - r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text|\t\.align|"+LABEL) - - r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+LOCALVARFP+") [*]/") - r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+OPERAND+") [*]/") - r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/") FUNCTIONS_NOT_RETURNING = { 'abort': None, @@ -792,6 +784,41 @@ super(ElfFunctionGcRootTracker, self).__init__( funcname, lines, filetag) + @classmethod + def init_regexp(cls): + cls.REG2LOC = dict((reg, LOC_REG | ((i+1)<<2)) + for i, reg in enumerate(cls.CALLEE_SAVE_REGISTERS)) + cls.TOP_OF_STACK = '0(%s)' % cls.ESP + cls.LOCALVARFP = cls.LOCALVAR + r"|-?\d*[(]%s[)]" % cls.EBP + + cls.r_localvarnofp = re.compile(cls.LOCALVAR) + cls.r_localvarfp = re.compile(cls.LOCALVARFP) + cls.r_localvar_esp = re.compile(r"(\d*)[(]%s[)]" % cls.ESP) + cls.r_localvar_ebp = re.compile(r"(-?\d*)[(]%s[)]" % cls.EBP) + + cls.r_functionstart = re.compile(r"\t.type\s+"+cls.LABEL+ + r",\s*[@]function\s*$") + cls.r_functionend = re.compile(r"\t.size\s+"+cls.LABEL+ + r",\s*[.]-"+cls.LABEL+"\s*$") + + cls.r_rel_label = re.compile(r"(\d+):\s*$") + cls.r_jump_rel_label = re.compile(r"\tj\w+\s+"+r"(\d+)f"+r"\s*$") + + cls.r_unaryinsn_star= re.compile(r"\t[a-z]\w*\s+[*]("+cls.OPERAND+ + r")\s*$") + cls.r_jmptable_item = re.compile(r"\t.(?:long|quad)\t"+cls.LABEL+ + r'(-"[A-Za-z0-9$]+")?\s*$') + cls.r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text|" + r"\t\.align|"+cls.LABEL) + + cls.r_gcroot_marker = re.compile(r"\t/[*] GCROOT ("+cls.LOCALVARFP+ + r") [*]/") + cls.r_gcnocollect_marker = re.compile(r"\t/[*] GC_NOCOLLECT ("+ + cls.OPERAND+r") [*]/") + cls.r_bottom_marker = re.compile(r"\t/[*] GC_STACK_BOTTOM [*]/") + + super(ElfFunctionGcRootTracker, cls).init_regexp() + def extract_immediate(self, value): if not value.startswith('$'): return None @@ -799,6 +826,19 @@ ElfFunctionGcRootTracker.init_regexp() +class Elf64FunctionGcRootTracker(ElfFunctionGcRootTracker): + WORD = 8 + BITS = 64 + SUFFIX = 'q' + ESP = '%rsp' + EBP = '%rbp' + EAX = '%rax' + CALLEE_SAVE_REGISTERS = ['%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15'] + LOCALVAR = (r"%rax|%rdx|%rcx|%rbx|%rsi|%rdi|%rbp|" + r"%r8|%r9|%r10|%r11|%r12|%r13|%r14|%r15|\d*[(]%rsp[)]") + +Elf64FunctionGcRootTracker.init_regexp() + class DarwinFunctionGcRootTracker(ElfFunctionGcRootTracker): format = 'darwin' @@ -821,6 +861,7 @@ class MsvcFunctionGcRootTracker(FunctionGcRootTracker): format = 'msvc' + SUFFIX = '' ESP = 'esp' EBP = 'ebp' EAX = 'eax' @@ -898,13 +939,6 @@ operand = operand.replace(name, str(value)) return operand - for name in ''' - push pop mov lea - xor sub add - '''.split(): - locals()['visit_' + name] = getattr(FunctionGcRootTracker, - 'visit_' + name + 'l') - visit_int = FunctionGcRootTracker.visit_nop # probably not GC pointers visit_cdq = FunctionGcRootTracker.visit_nop @@ -1068,6 +1102,10 @@ "missed the end of the previous function") yield False, functionlines +class Elf64AssemblerParser(AssemblerParser): + format = "elf64" + FunctionGcRootTracker = Elf64FunctionGcRootTracker + class DarwinAssemblerParser(AssemblerParser): format = "darwin" FunctionGcRootTracker = DarwinFunctionGcRootTracker @@ -1213,6 +1251,7 @@ PARSERS = { 'elf': ElfAssemblerParser, + 'elf64': Elf64AssemblerParser, 'darwin': DarwinAssemblerParser, 'mingw32': Mingw32AssemblerParser, 'msvc': MsvcAssemblerParser, @@ -1471,7 +1510,7 @@ # __________ debugging output __________ -def format_location(loc): +def format_location(loc, cls=ElfFunctionGcRootTracker): # A 'location' is a single number describing where a value is stored # across a call. It can be in one of the CALLEE_SAVE_REGISTERS, or # in the stack frame at an address relative to either %esp or %ebp. @@ -1483,23 +1522,23 @@ if loc == LOC_NOWHERE: return '?' reg = (loc >> 2) - 1 - return ElfFunctionGcRootTracker.CALLEE_SAVE_REGISTERS[reg] + return cls.CALLEE_SAVE_REGISTERS[reg] else: offset = loc & ~ LOC_MASK if kind == LOC_EBP_PLUS: - result = '(%ebp)' + result = '(%s)' % cls.EBP elif kind == LOC_EBP_MINUS: - result = '(%ebp)' + result = '(%s)' % cls.EBP offset = -offset elif kind == LOC_ESP_PLUS: - result = '(%esp)' + result = '(%s)' % cls.ESP else: assert 0, kind if offset != 0: result = str(offset) + result return result -def format_callshape(shape): +def format_callshape(shape, cls=ElfFunctionGcRootTracker): # A 'call shape' is a tuple of locations in the sense of format_location(). # They describe where in a function frame interesting values are stored, # when this function executes a 'call' instruction. @@ -1512,12 +1551,15 @@ # shape[4] is where the fn saved its own caller's %ebp value # shape[>=5] are GC roots: where the fn has put its local GCPTR vars # + # On 64-bit, there are 6 registers instead of 4 that are callee-saved. + # assert isinstance(shape, tuple) - assert len(shape) >= 5 - result = [format_location(loc) for loc in shape] + N = len(cls.CALLEE_SAVE_REGISTERS) + 1 + assert len(shape) >= N + result = [format_location(loc, cls) for loc in shape] return '{%s | %s | %s}' % (result[0], - ', '.join(result[1:5]), - ', '.join(result[5:])) + ', '.join(result[1:N]), + ', '.join(result[N:])) # __________ table compression __________ From arigo at codespeak.net Sat Mar 27 20:19:18 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 20:19:18 +0100 (CET) Subject: [pypy-svn] r72970 - pypy/branch/asmgcc-64/pypy/translator/c/gcc Message-ID: <20100327191918.09EF5282BF1@codespeak.net> Author: arigo Date: Sat Mar 27 20:19:17 2010 New Revision: 72970 Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Log: Fixes for tests. Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Sat Mar 27 20:19:17 2010 @@ -526,6 +526,8 @@ # gcc -fno-unit-at-a-time. return self.insns_for_copy(source, target) + visit_mov = visit_movX + def visit_pushX(self, line): match = self.r_unaryinsn.match(line) source = match.group(1) @@ -1522,7 +1524,10 @@ if loc == LOC_NOWHERE: return '?' reg = (loc >> 2) - 1 - return cls.CALLEE_SAVE_REGISTERS[reg] + result = cls.CALLEE_SAVE_REGISTERS[reg] + if '%' not in result: # xxx messy, to avoid fixing tons of tests + result = '%' + result + return result else: offset = loc & ~ LOC_MASK if kind == LOC_EBP_PLUS: @@ -1534,6 +1539,8 @@ result = '(%s)' % cls.ESP else: assert 0, kind + if '%' not in result: # xxx messy, to avoid fixing tons of tests + result = result[:1] + '%' + result[1:] if offset != 0: result = str(offset) + result return result From fijal at codespeak.net Sat Mar 27 20:33:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 20:33:39 +0100 (CET) Subject: [pypy-svn] r72971 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test test/zfec Message-ID: <20100327193339.EF2C2282B9C@codespeak.net> Author: fijal Date: Sat Mar 27 20:33:37 2010 New Revision: 72971 Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/intobject.h pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/zfec/ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Log: (zooko, fijal) Added PyInt_Check Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sat Mar 27 20:33:37 2010 @@ -40,5 +40,6 @@ import pypy.module.cpyext.stringobject import pypy.module.cpyext.tupleobject import pypy.module.cpyext.dictobject +import pypy.module.cpyext.intobject # now that all rffi_platform.Struct types are registered, configure them api.configure_types() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Sat Mar 27 20:33:37 2010 @@ -37,6 +37,7 @@ #include "descrobject.h" #include "tupleobject.h" #include "dictobject.h" +#include "intobject.h" #include Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/intobject.h ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/intobject.h Sat Mar 27 20:33:37 2010 @@ -0,0 +1,13 @@ + +/* Int object interface */ + +#ifndef Py_INTOBJECT_H +#define Py_INTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ Added: pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py Sat Mar 27 20:33:37 2010 @@ -0,0 +1,12 @@ + +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL +from pypy.module.cpyext.api import general_check + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyInt_Check(space, w_obj): + """Return true if o is of type PyInt_Type or a subtype of + PyInt_Type. + + Allowed subtypes to be accepted.""" + return general_check(space, w_obj, space.w_int) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sat Mar 27 20:33:37 2010 @@ -3291,14 +3291,6 @@ raise NotImplementedError @cpython_api([PyObject], rffi.INT_real) -def PyInt_Check(space, o): - """Return true if o is of type PyInt_Type or a subtype of - PyInt_Type. - - Allowed subtypes to be accepted.""" - raise NotImplementedError - - at cpython_api([PyObject], rffi.INT_real) def PyInt_CheckExact(space, o): """Return true if o is of type PyInt_Type, but not a subtype of PyInt_Type. Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py Sat Mar 27 20:33:37 2010 @@ -0,0 +1,17 @@ + +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +class AppTestIntObject(AppTestCpythonExtensionBase): + def test_intobject(self): + module = self.import_extension('foo', [ + ("check_int", "METH_VARARGS", + """ + PyObject* a = PyTuple_GetItem(args, 0); + if (PyInt_Check(a)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + """)]) + assert module.check_int(3) + assert module.check_int(True) + assert not module.check_int((1, 2, 3)) From xoraxax at codespeak.net Sat Mar 27 20:46:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 20:46:21 +0100 (CET) Subject: [pypy-svn] r72972 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327194621.41E95282B9C@codespeak.net> Author: xoraxax Date: Sat Mar 27 20:46:19 2010 New Revision: 72972 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Output error message if a wrapper function is missing and we cannot fill the typeobject correctly because of it. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sat Mar 27 20:46:19 2010 @@ -63,7 +63,7 @@ # XXX support PyObject_HashNotImplemented state = space.fromcache(State) for method_name, slot_name, _, wrapper_func, wrapper_func_kwds, doc in state.slotdefs: # XXX use UI - if method_name in dict_w or (wrapper_func is None and wrapper_func_kwds is None): + if method_name in dict_w: continue # XXX is this rpython? if len(slot_name) == 1: @@ -77,6 +77,9 @@ func_voidp = rffi.cast(rffi.VOIDP_real, func) if not func: continue + if wrapper_func is None and wrapper_func_kwds is None: + print >>sys.stderr, method_name, "used by the type but no wrapper function defined!" + continue dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp) From fijal at codespeak.net Sat Mar 27 20:57:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 20:57:22 +0100 (CET) Subject: [pypy-svn] r72973 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327195722.CB92C282B90@codespeak.net> Author: fijal Date: Sat Mar 27 20:57:21 2010 New Revision: 72973 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py Log: (zooko, fijal) PyInt_FromLong and PyInt_AsLong Modified: pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/intobject.py Sat Mar 27 20:57:21 2010 @@ -10,3 +10,18 @@ Allowed subtypes to be accepted.""" return general_check(space, w_obj, space.w_int) + + at cpython_api([lltype.Signed], PyObject) +def PyInt_FromLong(space, ival): + """Create a new integer object with a value of ival. + + """ + return space.wrap(ival) + + at cpython_api([PyObject], lltype.Signed, error=-1) +def PyInt_AsLong(space, w_obj): + """Will first attempt to cast the object to a PyIntObject, if it is not + already one, and then return its value. If there is an error, -1 is + returned, and the caller should check PyErr_Occurred() to find out whether + there was an error, or whether the value just happened to be -1.""" + return space.int_w(w_obj) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py Sat Mar 27 20:57:21 2010 @@ -3,6 +3,7 @@ class AppTestIntObject(AppTestCpythonExtensionBase): def test_intobject(self): + import sys module = self.import_extension('foo', [ ("check_int", "METH_VARARGS", """ @@ -11,7 +12,25 @@ Py_RETURN_TRUE; } Py_RETURN_FALSE; - """)]) + """), + ("add_one", "METH_VARARGS", + """ + PyObject *a = PyTuple_GetItem(args, 0); + long x = PyInt_AsLong(a); + if (x == -1) { + if (PyErr_Occurred()) { + return NULL; + } + } + PyObject *ret = PyInt_FromLong(x + 1); + return ret; + """ + ) + ]) assert module.check_int(3) assert module.check_int(True) assert not module.check_int((1, 2, 3)) + for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]: + assert module.add_one(i) == i + 1 + assert type(module.add_one(3)) is int + raises(TypeError, module.add_one, None) From arigo at codespeak.net Sat Mar 27 21:06:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Mar 2010 21:06:41 +0100 (CET) Subject: [pypy-svn] r72974 - pypy/branch/asmgcc-64/pypy/translator/c/gcc Message-ID: <20100327200641.4DCA9282B90@codespeak.net> Author: arigo Date: Sat Mar 27 21:06:14 2010 New Revision: 72974 Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Log: Whack whack whack. Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py Sat Mar 27 21:06:14 2010 @@ -5,13 +5,17 @@ LOC_MASK = 0x03 LOC_NOWHERE = LOC_REG | 0 -def frameloc_esp(offset): - assert offset >= 0 - assert offset % 4 == 0 - return LOC_ESP_PLUS | offset +def frameloc_esp(offset, WORD=4): + assert offset % WORD == 0 + if offset >= 0: + return LOC_ESP_PLUS | offset + else: + # On 64-bit, the "red zone" might need access to e.g. -8(%esp). + # But such positions should never be used across a CALL... + raise AssertionError(offset) -def frameloc_ebp(offset): - assert offset % 4 == 0 +def frameloc_ebp(offset, WORD=4): + assert offset % WORD == 0 if offset >= 0: return LOC_EBP_PLUS | offset else: @@ -22,7 +26,7 @@ pass somenewvalue = SomeNewValue() -class LocalVar(object): +class LocalVarAbstract(object): # A local variable location at position 'ofs_from_frame_end', # which is counted from the end of the stack frame (so it is always # negative, unless it refers to arguments of the current function). @@ -37,7 +41,7 @@ return hash(self.ofs_from_frame_end) def __cmp__(self, other): - if isinstance(other, LocalVar): + if isinstance(other, LocalVarAbstract): return cmp(self.ofs_from_frame_end, other.ofs_from_frame_end) else: return 1 @@ -48,12 +52,18 @@ # try to use esp-relative addressing ofs_from_esp = framesize + self.ofs_from_frame_end if ofs_from_esp % 2 == 0: - return frameloc_esp(ofs_from_esp) + return frameloc_esp(ofs_from_esp, self.WORD) # we can get an odd value if the framesize is marked as bogus # by visit_andl() assert uses_frame_pointer - ofs_from_ebp = self.ofs_from_frame_end + 4 - return frameloc_ebp(ofs_from_ebp) + ofs_from_ebp = self.ofs_from_frame_end + self.WORD + return frameloc_ebp(ofs_from_ebp, self.WORD) + +class LocalVar32(LocalVarAbstract): + WORD = 4 + +class LocalVar64(LocalVarAbstract): + WORD = 8 class Insn(object): @@ -98,7 +108,7 @@ # the 3 registers above are then used to pass arguments pass else: - assert (isinstance(localvar, LocalVar) and + assert (isinstance(localvar, LocalVarAbstract) and localvar.ofs_from_frame_end > 0), ( "must come from an argument to the function, got %r" % (localvar,)) @@ -220,13 +230,11 @@ class InsnPrologue(Insn): def __setattr__(self, attr, value): if attr == 'framesize': - assert value == 4, ("unrecognized function prologue - " - "only supports push %ebp; movl %esp, %ebp") + assert value in (4,8), ("unrecognized function prologue - " + "only supports push %ebp; movl %esp, %ebp") Insn.__setattr__(self, attr, value) class InsnEpilogue(Insn): def __init__(self, framesize=None): if framesize is not None: self.framesize = framesize - - Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Sat Mar 27 21:06:14 2010 @@ -9,7 +9,8 @@ from pypy.translator.c.gcc.instruction import InsnGCROOT from pypy.translator.c.gcc.instruction import InsnStackAdjust from pypy.translator.c.gcc.instruction import InsnCannotFollowEsp -from pypy.translator.c.gcc.instruction import LocalVar, somenewvalue +from pypy.translator.c.gcc.instruction import LocalVar32, LocalVar64 +from pypy.translator.c.gcc.instruction import somenewvalue from pypy.translator.c.gcc.instruction import frameloc_esp, frameloc_ebp from pypy.translator.c.gcc.instruction import LOC_REG, LOC_NOWHERE, LOC_MASK from pypy.translator.c.gcc.instruction import LOC_EBP_PLUS, LOC_EBP_MINUS @@ -18,8 +19,8 @@ class FunctionGcRootTracker(object): skip = 0 WORD = 4 - BITS = 32 SUFFIX = 'l' + LocalVar = LocalVar32 @classmethod def init_regexp(cls): @@ -74,7 +75,7 @@ if self.is_stack_bottom: retaddr = LOC_NOWHERE # end marker for asmgcroot.py elif self.uses_frame_pointer: - retaddr = frameloc_ebp(4) + retaddr = frameloc_ebp(self.WORD) else: retaddr = frameloc_esp(insn.framesize) shape = [retaddr] @@ -84,7 +85,7 @@ shape.append(LOC_NOWHERE) gcroots = [] for localvar, tag in insn.gcroots.items(): - if isinstance(localvar, LocalVar): + if isinstance(localvar, self.LocalVar): loc = localvar.getlocation(insn.framesize, self.uses_frame_pointer) elif localvar in self.REG2LOC: @@ -271,16 +272,16 @@ ofs_from_esp += int(match.group(2) or '0') localvar = ofs_from_esp - insn.framesize assert localvar != 0 # that's the return address - return LocalVar(localvar, hint=hint) + return self.LocalVar(localvar, hint=hint) elif self.uses_frame_pointer: match = self.r_localvar_ebp.match(localvar) if match: ofs_from_ebp = int(match.group(1) or '0') if self.format == 'msvc': ofs_from_ebp += int(match.group(2) or '0') - localvar = ofs_from_ebp - 4 + localvar = ofs_from_ebp - self.WORD assert localvar != 0 # that's the return address - return LocalVar(localvar, hint='ebp') + return self.LocalVar(localvar, hint='ebp') return localvar for insn in self.insns: @@ -402,8 +403,10 @@ 'bswap', 'bt', 'rdtsc', # zero-extending moves should not produce GC pointers 'movz', - # quadword operations + # quadword operations: ignored on 32-bit 'movq', + # conversely, ignore 32-bit operations on 64-bit + 'xorl', 'movl', 'addl', 'subl', 'andl', 'orl', 'leal', ]) visit_movb = visit_nop @@ -462,6 +465,7 @@ '''.split(): locals()['visit_cmov' + name] = binary_insn locals()['visit_cmov' + name + 'X'] = binary_insn + IGNORE_OPS_WITH_PREFIXES['cmov' + name + 'l'] = True # for 64-bit def visit_andX(self, line): match = self.r_binaryinsn.match(line) @@ -502,13 +506,15 @@ def insns_for_copy(self, source, target): source = self.replace_symbols(source) target = self.replace_symbols(target) - if source == self.ESP or target == self.ESP: - raise UnrecognizedOperation('%s -> %s' % (source, target)) - elif self.r_localvar.match(target): + if self.r_localvar.match(target): if self.r_localvar.match(source): return [InsnCopyLocal(source, target)] - else: + elif source != self.ESP: return [InsnSetLocal(target, [source])] + else: + return [InsnSetLocal(target)] # obscure case + elif source == self.ESP or target == self.ESP: + raise UnrecognizedOperation('%s -> %s' % (source, target)) else: return [] @@ -555,7 +561,7 @@ def _visit_epilogue(self): if not self.uses_frame_pointer: raise UnrecognizedOperation('epilogue without prologue') - return [InsnEpilogue(4)] + return [InsnEpilogue(self.WORD)] def visit_leave(self, line): return self._visit_epilogue() + self._visit_pop(self.EBP) @@ -739,7 +745,7 @@ lineoffset = self.labels[target].lineno - self.currentlineno if lineoffset >= 0: assert lineoffset in (1,2) - return [InsnStackAdjust(-4)] + return [InsnStackAdjust(-self.WORD)] insns = [InsnCall(target, self.currentlineno), InsnSetLocal(self.EAX)] # the result is there @@ -767,6 +773,7 @@ LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)' OFFSET_LABELS = 2**30 LOCALVAR = r"%eax|%edx|%ecx|%ebx|%esi|%edi|%ebp|\d*[(]%esp[)]" + RED_ZONE = 0 FUNCTIONS_NOT_RETURNING = { 'abort': None, @@ -795,7 +802,10 @@ cls.r_localvarnofp = re.compile(cls.LOCALVAR) cls.r_localvarfp = re.compile(cls.LOCALVARFP) - cls.r_localvar_esp = re.compile(r"(\d*)[(]%s[)]" % cls.ESP) + if cls.RED_ZONE < 0: + cls.r_localvar_esp = re.compile(r"(-?\d*)[(]%s[)]" % cls.ESP) + else: + cls.r_localvar_esp = re.compile(r"(\d*)[(]%s[)]" % cls.ESP) cls.r_localvar_ebp = re.compile(r"(-?\d*)[(]%s[)]" % cls.EBP) cls.r_functionstart = re.compile(r"\t.type\s+"+cls.LABEL+ @@ -830,14 +840,16 @@ class Elf64FunctionGcRootTracker(ElfFunctionGcRootTracker): WORD = 8 - BITS = 64 SUFFIX = 'q' + LocalVar = LocalVar64 + ESP = '%rsp' EBP = '%rbp' EAX = '%rax' CALLEE_SAVE_REGISTERS = ['%rbp', '%rbx', '%r12', '%r13', '%r14', '%r15'] LOCALVAR = (r"%rax|%rdx|%rcx|%rbx|%rsi|%rdi|%rbp|" - r"%r8|%r9|%r10|%r11|%r12|%r13|%r14|%r15|\d*[(]%rsp[)]") + r"%r8|%r9|%r10|%r11|%r12|%r13|%r14|%r15|-?\d*[(]%rsp[)]") + RED_ZONE = -128 Elf64FunctionGcRootTracker.init_regexp() @@ -1068,8 +1080,9 @@ tracker.funcname) table = tracker.computegcmaptable(self.verbose) if self.verbose > 1: + cls = self.FunctionGcRootTracker for label, state in table: - print >> sys.stderr, label, '\t', format_callshape(state) + print >> sys.stderr, label, '\t', format_callshape(state, cls) table = compress_gcmaptable(table) if self.shuffle and random.random() < 0.5: self.gcmaptable[:0] = table @@ -1104,7 +1117,7 @@ "missed the end of the previous function") yield False, functionlines -class Elf64AssemblerParser(AssemblerParser): +class Elf64AssemblerParser(ElfAssemblerParser): format = "elf64" FunctionGcRootTracker = Elf64FunctionGcRootTracker @@ -1349,6 +1362,8 @@ """ else: + if self.WORD == 8: + xxxxxxxxxx print >> output, "\t.text" print >> output, "\t.globl %s" % _globalname('pypy_asm_stackwalk') _variant(elf='.type pypy_asm_stackwalk, @function', @@ -1660,6 +1675,8 @@ format = 'darwin' elif sys.platform == 'win32': format = 'mingw32' + elif sys.maxint > 2147483647: + format = 'elf64' else: format = 'elf' while len(sys.argv) > 1: From getxsick at codespeak.net Sat Mar 27 21:28:35 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sat, 27 Mar 2010 21:28:35 +0100 (CET) Subject: [pypy-svn] r72975 - pypy/trunk/pypy/tool Message-ID: <20100327202835.CB78E282B90@codespeak.net> Author: getxsick Date: Sat Mar 27 21:28:26 2010 New Revision: 72975 Modified: pypy/trunk/pypy/tool/runsubprocess.py Log: replace deprecated popen2() by Popen() Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Sat Mar 27 21:28:26 2010 @@ -44,8 +44,9 @@ # do this at import-time, when the process is still tiny _source = os.path.dirname(os.path.abspath(__file__)) _source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc' - _child_stdin, _child_stdout = os.popen2( - "'%s' '%s'" % (sys.executable, _source)) + args = ["'%s' '%s'" % (sys.executable, _source)] + pipe = Popen(args, stdout=PIPE, stdin=PIPE, shell=True, close_fds=True) + (_child_stdin, _child_stdout) = (pipe.stdin, pipe.stdout) def _run(*args): _child_stdin.write('%r\n' % (args,)) From xoraxax at codespeak.net Sat Mar 27 21:40:14 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 21:40:14 +0100 (CET) Subject: [pypy-svn] r72976 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327204014.73092282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 21:40:12 2010 New Revision: 72976 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py Log: Introduce correct refcount handling for (borrowed) exceptions. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 21:40:12 2010 @@ -136,10 +136,12 @@ raise state = space.fromcache(State) e.normalize_exception(space) - state.exc_type = e.w_type - state.exc_value = e.get_w_value(space) + state.set_exception(e.w_type, e.get_w_value(space)) return api_function.error_value finally: + if api_function.borrowed: + state = space.fromcache(State) + state.last_container = 0 from pypy.module.cpyext.macros import Py_DECREF for arg in to_decref: Py_DECREF(space, arg) @@ -322,7 +324,10 @@ @cpython_api([PyObject], lltype.Void, external=False) def register_container(space, container): state = space.fromcache(State) - container_ptr = rffi.cast(ADDR, container) + if not container: # self-managed + container_ptr = -1 + else: + container_ptr = rffi.cast(ADDR, container) assert not state.last_container, "Last container was not fetched" state.last_container = container_ptr @@ -332,6 +337,8 @@ state.last_container = 0 if not container_ptr: raise NullPointerException + if container_ptr == -1: + return borrowees = state.borrow_mapping.get(container_ptr) if borrowees is None: state.borrow_mapping[container_ptr] = borrowees = {} @@ -371,12 +378,10 @@ except OperationError, e: failed = True e.normalize_exception(space) - state.exc_type = e.w_type - state.exc_value = e.get_w_value(space) + state.set_exception(e.w_type, e.get_w_value(space)) except BaseException, e: failed = True - state.exc_type = space.w_SystemError - state.exc_value = space.wrap(str(e)) + state.set_exception(space.w_SystemError, space.wrap(str(e))) import traceback traceback.print_exc() else: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Sat Mar 27 21:40:12 2010 @@ -1,25 +1,25 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref +from pypy.module.cpyext.api import cpython_api, PyObject, make_ref,\ + register_container from pypy.module.cpyext.state import State @cpython_api([PyObject, rffi.CCHARP], lltype.Void) def PyErr_SetString(space, w_type, message_ptr): message = rffi.charp2str(message_ptr) state = space.fromcache(State) - state.exc_type = w_type - state.exc_value = space.call_function(w_type, space.wrap(message)) + state.set_exception(w_type, space.wrap(message)) - at cpython_api([], PyObject) + at cpython_api([], PyObject, borrowed=True) def PyErr_Occurred(space): state = space.fromcache(State) + register_container(space, None) return state.exc_value @cpython_api([], lltype.Void) def PyErr_Clear(space): state = space.fromcache(State) - state.exc_type = None - state.exc_value = None + state.clear_exception() @cpython_api([], lltype.Void) def PyErr_BadInternalCall(space): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Sat Mar 27 21:40:12 2010 @@ -1,4 +1,5 @@ from pypy.rlib.objectmodel import we_are_translated +from pypy.rpython.lltypesystem import rffi, lltype from pypy.lib.identity_dict import identity_dict from pypy.interpreter.error import OperationError from pypy.rpython.lltypesystem import lltype @@ -19,12 +20,29 @@ self.exc_type = None self.exc_value = None + def set_exception(self, w_type, w_value): + self.clear_exception() + self.exc_type = w_type + self.exc_value = w_value + + def clear_exception(self): + from pypy.module.cpyext.macros import Py_DECREF + from pypy.module.cpyext.api import make_ref, ADDR + # handling of borrowed objects, remove when we have + # a weakkeydict + exc_value = make_ref(self.space, self.exc_value, borrowed=True) + if exc_value: + Py_DECREF(self.space, exc_value) + containee_ptr = rffi.cast(ADDR, exc_value) + del self.borrowed_objects[containee_ptr] + self.exc_type = None + self.exc_value = None + def check_and_raise_exception(self): exc_value = self.exc_value exc_type = self.exc_type if exc_type is not None or exc_value is not None: - self.exc_value = None - self.exc_type = None + self.clear_exception() op_err = OperationError(exc_type, exc_value) raise op_err From fijal at codespeak.net Sat Mar 27 22:02:42 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 22:02:42 +0100 (CET) Subject: [pypy-svn] r72977 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327210242.E1211282B90@codespeak.net> Author: fijal Date: Sat Mar 27 22:02:41 2010 New Revision: 72977 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Log: (zooko, fijal) Add a comment Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Sat Mar 27 22:02:41 2010 @@ -23,6 +23,7 @@ @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) def PyTuple_SetItem(space, w_t, pos, w_obj): if not PyTuple_Check(space, w_t): + # XXX this should also steal a reference, test it!!! PyErr_BadInternalCall(space) assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj From getxsick at codespeak.net Sat Mar 27 22:12:28 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sat, 27 Mar 2010 22:12:28 +0100 (CET) Subject: [pypy-svn] r72978 - in pypy/trunk/pypy/rlib: . test Message-ID: <20100327211228.0DDB1282B90@codespeak.net> Author: getxsick Date: Sat Mar 27 22:12:27 2010 New Revision: 72978 Modified: pypy/trunk/pypy/rlib/_rsocket_rffi.py pypy/trunk/pypy/rlib/test/test_rsocket.py Log: Correct the order of sockaddr_in6. Add extra tests. Modified: pypy/trunk/pypy/rlib/_rsocket_rffi.py ============================================================================== --- pypy/trunk/pypy/rlib/_rsocket_rffi.py (original) +++ pypy/trunk/pypy/rlib/_rsocket_rffi.py Sat Mar 27 22:12:27 2010 @@ -259,8 +259,8 @@ CConfig.sockaddr_in6 = platform.Struct('struct sockaddr_in6', [('sin6_family', rffi.INT), ('sin6_port', rffi.USHORT), - ('sin6_addr', CConfig.in6_addr), ('sin6_flowinfo', rffi.INT), + ('sin6_addr', CConfig.in6_addr), ('sin6_scope_id', rffi.INT)]) CConfig.sockaddr_un = platform.Struct('struct sockaddr_un', Modified: pypy/trunk/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rsocket.py (original) +++ pypy/trunk/pypy/rlib/test/test_rsocket.py Sat Mar 27 22:12:27 2010 @@ -78,6 +78,19 @@ py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" % (address_list,)) + name, aliases, address_list = gethostbyaddr('localhost') + allnames = [name] + aliases + for n in allnames: + assert isinstance(n, str) + if sys.platform != 'win32': + assert 'localhost' in allnames + for a in address_list: + if isinstance(a, INET6Address) and a.get_host() == "::1": + break # ok + else: + py.test.fail("could not find the ::1 IPv6 address in %r" + % (address_list,)) + def test_getservbyname(): assert getservbyname('http') == 80 assert getservbyname('http', 'tcp') == 80 From xoraxax at codespeak.net Sat Mar 27 22:13:07 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 22:13:07 +0100 (CET) Subject: [pypy-svn] r72979 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327211307.2FF4F282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 22:13:05 2010 New Revision: 72979 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Log: Let BadInternalCall raise a TypeError instead of a SystemError. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Sat Mar 27 22:13:05 2010 @@ -23,5 +23,5 @@ @cpython_api([], lltype.Void) def PyErr_BadInternalCall(space): - raise OperationError(space.w_SystemError, space.wrap("Bad internal call!")) + raise OperationError(space.w_TypeError, space.wrap("Bad internal call!")) From xoraxax at codespeak.net Sat Mar 27 22:13:29 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 22:13:29 +0100 (CET) Subject: [pypy-svn] r72980 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327211329.2A80A282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 22:13:27 2010 New Revision: 72980 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Log: Refactor exception handling. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 22:13:27 2010 @@ -110,50 +110,55 @@ def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed, error) + func.api_func = api_function if error is _NOT_SPECIFIED: raise ValueError("function %s has no return value for exceptions" % func) - def unwrapper(space, *args): - "NOT_RPYTHON: XXX unsure" - newargs = [] - to_decref = [] - for i, arg in enumerate(args): - if api_function.argtypes[i] is PyObject: - if (isinstance(arg, W_Root) and - not api_function.argnames[i].startswith('w_')): - arg = make_ref(space, arg) - to_decref.append(arg) - elif (not isinstance(arg, W_Root) and - api_function.argnames[i].startswith('w_')): - arg = from_ref(space, arg) - newargs.append(arg) - try: + def make_unwrapper(catch_exception): + def unwrapper(space, *args): + "NOT_RPYTHON: XXX unsure" + newargs = [] + to_decref = [] + for i, arg in enumerate(args): + if api_function.argtypes[i] is PyObject: + if (isinstance(arg, W_Root) and + not api_function.argnames[i].startswith('w_')): + arg = make_ref(space, arg) + to_decref.append(arg) + elif (not isinstance(arg, W_Root) and + api_function.argnames[i].startswith('w_')): + arg = from_ref(space, arg) + newargs.append(arg) try: - return func(space, *newargs) - except OperationError, e: - if not hasattr(api_function, "error_value"): - raise - state = space.fromcache(State) - e.normalize_exception(space) - state.set_exception(e.w_type, e.get_w_value(space)) - return api_function.error_value - finally: - if api_function.borrowed: - state = space.fromcache(State) - state.last_container = 0 - from pypy.module.cpyext.macros import Py_DECREF - for arg in to_decref: - Py_DECREF(space, arg) + try: + return func(space, *newargs) + except OperationError, e: + if not catch_exception: + raise + if not hasattr(api_function, "error_value"): + raise + state = space.fromcache(State) + e.normalize_exception(space) + state.set_exception(e.w_type, e.get_w_value(space)) + return api_function.error_value + finally: + if api_function.borrowed: + state = space.fromcache(State) + state.last_container = 0 + from pypy.module.cpyext.macros import Py_DECREF + for arg in to_decref: + Py_DECREF(space, arg) + unwrapper.func = func + unwrapper.api_func = api_function + return unwrapper - func.api_func = api_function - unwrapper.api_func = api_function - unwrapper.func = func - unwrapper.__name__ = "uw(%s)" % (func.__name__, ) + unwrapper_True = make_unwrapper(True) + unwrapper_False = make_unwrapper(False) if external: FUNCTIONS[func.func_name] = api_function - INTERPLEVEL_API[func.func_name] = unwrapper - return unwrapper + INTERPLEVEL_API[func.func_name] = unwrapper_True + return unwrapper_False return decorate def cpython_api_c(): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_tupleobject.py Sat Mar 27 22:13:27 2010 @@ -4,7 +4,6 @@ class TestTupleObject(BaseApiTest): def test_tupleobject(self, space, api): - py.test.skip("Needs API refactoring, done by amaury") assert not api.PyTuple_Check(space.w_None) assert api.PyTuple_SetItem(space.w_None, 0, space.w_None) == -1 api.PyErr_Clear() From xoraxax at codespeak.net Sat Mar 27 22:17:12 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 22:17:12 +0100 (CET) Subject: [pypy-svn] r72981 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327211712.4EBC5282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 22:17:10 2010 New Revision: 72981 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Log: Revert 72979, this was changed in 2.6. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Sat Mar 27 22:17:10 2010 @@ -23,5 +23,5 @@ @cpython_api([], lltype.Void) def PyErr_BadInternalCall(space): - raise OperationError(space.w_TypeError, space.wrap("Bad internal call!")) + raise OperationError(space.w_SystemError, space.wrap("Bad internal call!")) From fijal at codespeak.net Sat Mar 27 22:19:58 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 22:19:58 +0100 (CET) Subject: [pypy-svn] r72982 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327211958.2C06D282B90@codespeak.net> Author: fijal Date: Sat Mar 27 22:19:56 2010 New Revision: 72982 Added: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Log: Implement a couple of list operations Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sat Mar 27 22:19:56 2010 @@ -41,5 +41,6 @@ import pypy.module.cpyext.tupleobject import pypy.module.cpyext.dictobject import pypy.module.cpyext.intobject +import pypy.module.cpyext.listobject # now that all rffi_platform.Struct types are registered, configure them api.configure_types() Added: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Sat Mar 27 22:19:56 2010 @@ -0,0 +1,38 @@ + +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ + Py_ssize_t +from pypy.module.cpyext.api import general_check +from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall +from pypy.module.cpyext.macros import Py_XDECREF +from pypy.objspace.std.listobject import W_ListObject +from pypy.interpreter.error import OperationError + + at cpython_api([Py_ssize_t], PyObject) +def PyList_New(space, len): + """Return a new list of length len on success, or NULL on failure. + + If length is greater than zero, the returned list object's items are + set to NULL. Thus you cannot use abstract API functions such as + PySequence_SetItem() or expose the object to Python code before + setting all items to a real object with PyList_SetItem(). + """ + return space.newlist([None] * len) + + at cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1) +def PyList_SetItem(space, w_list, index, w_item): + """Set the item at index index in list to item. Return 0 on success + or -1 on failure. + + This function "steals" a reference to item and discards a reference to + an item already in the list at the affected position. + """ + Py_XDECREF(space, w_item) + if not isinstance(w_list, W_ListObject): + PyErr_BadInternalCall() + wrappeditems = w_list.wrappeditems + if index < 0 or index >= len(wrappeditems): + raise OperationError(space.w_IndexError, space.wrap( + "list assignment index out of range")) + wrappeditems[index] = w_item + return 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sat Mar 27 22:19:56 2010 @@ -3452,19 +3452,6 @@ """ raise NotImplementedError - at cpython_api([Py_ssize_t], PyObject) -def PyList_New(space, len): - """Return a new list of length len on success, or NULL on failure. - - If length is greater than zero, the returned list object's items are - set to NULL. Thus you cannot use abstract API functions such as - PySequence_SetItem() or expose the object to Python code before - setting all items to a real object with PyList_SetItem(). - - This function used an int for size. This might require - changes in your code for properly supporting 64-bit systems.""" - raise NotImplementedError - @cpython_api([PyObject], Py_ssize_t) def PyList_Size(space, list): """ Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Sat Mar 27 22:19:56 2010 @@ -0,0 +1,44 @@ + +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +class AppTestListObject(AppTestCpythonExtensionBase): + def test_listobject(self): + import sys + module = self.import_extension('foo', [ + ("newlist", "METH_NOARGS", + """ + PyObject *lst = PyList_New(3); + PyList_SetItem(lst, 0, PyInt_FromLong(3)); + PyList_SetItem(lst, 2, PyInt_FromLong(1000)); + PyList_SetItem(lst, 1, PyInt_FromLong(-5)); + return lst; + """ + ), + ("setlistitem", "METH_VARARGS", + """ + PyObject *l = PyTuple_GetItem(args, 0); + int index = PyInt_AsLong(PyTuple_GetItem(args, 1)); + Py_INCREF(Py_None); + int res = PyList_SetItem(l, index, Py_None); + if (res == -1) { + return NULL; + } + Py_INCREF(Py_None); + return Py_None; + """ + ) + ]) + l = module.newlist() + assert l == [3, -5, 1000] + module.setlistitem(l, 0) + assert l[0] is None + + class L(list): + def __setitem__(self): + self.append("XYZ") + + l = L([1]) + module.setlistitem(l, 0) + assert len(l) == 1 + + raises(TypeError, module.setlistitem, (1, 2, 3), 0) From agaynor at codespeak.net Sat Mar 27 22:21:18 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sat, 27 Mar 2010 22:21:18 +0100 (CET) Subject: [pypy-svn] r72983 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100327212118.0B9E0282B90@codespeak.net> Author: agaynor Date: Sat Mar 27 22:21:16 2010 New Revision: 72983 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: Implement PyDict_{Get, Set}Item, and added dict tests. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Sat Mar 27 22:21:16 2010 @@ -12,6 +12,20 @@ w_type = space.w_dict return general_check(space, w_obj, w_type) + at cpython_api([PyObject, PyObject], PyObject) +def PyDict_GetItem(space, w_dict, w_key): + if PyDict_Check(space, w_dict): + return space.getitem(w_dict, w_key) + else: + PyErr_BadInternalCall(space) + + at cpython_api([PyObject, PyObject, PyObject], rffi.INT_real, error=-1) +def PyDict_SetItem(space, w_dict, w_key, w_obj): + if PyDict_Check(space, w_dict): + space.setitem(w_dict, w_key, w_obj) + return 0 + else: + PyErr_BadInternalCall(space) @cpython_api([PyObject, rffi.CCHARP, PyObject], rffi.INT_real, error=-1) def PyDict_SetItemString(space, w_dict, key_ptr, w_obj): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sat Mar 27 22:21:16 2010 @@ -3,6 +3,7 @@ #include +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None typedef void* Py_buffer; Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Sat Mar 27 22:21:16 2010 @@ -0,0 +1,31 @@ +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + + +class AppTestDictObject(AppTestCpythonExtensionBase): + def test_dict(self): + module = self.import_extension("foo", [ + ("test_dict_create", "METH_NOARGS", + """ + PyObject *p = PyDict_New(); + return p; + """), + ("test_dict_getitem", "METH_VARARGS", + """ + return PyDict_GetItem(PyTuple_GetItem(args, 0), PyTuple_GetItem(args, 1)); + """), + ("test_dict_setitem", "METH_VARARGS", + """ + PyDict_SetItem( + PyTuple_GetItem(args, 0), + PyTuple_GetItem(args, 1), + PyTuple_GetItem(args, 2) + ); + Py_RETURN_NONE; + """), + ]) + + assert module.test_dict_create() == {} + assert module.test_dict_getitem({"a": 72}, "a") == 72 + d = {} + module.test_dict_setitem(d, "c", 72) + assert d["c"] == 72 From fijal at codespeak.net Sat Mar 27 22:22:49 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 22:22:49 +0100 (CET) Subject: [pypy-svn] r72984 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327212249.7E3A6282B90@codespeak.net> Author: fijal Date: Sat Mar 27 22:22:48 2010 New Revision: 72984 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Log: (zooko, fijal) Fix test Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Sat Mar 27 22:22:48 2010 @@ -29,7 +29,7 @@ """ Py_XDECREF(space, w_item) if not isinstance(w_list, W_ListObject): - PyErr_BadInternalCall() + PyErr_BadInternalCall(space) wrappeditems = w_list.wrappeditems if index < 0 or index >= len(wrappeditems): raise OperationError(space.w_IndexError, space.wrap( Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Sat Mar 27 22:22:48 2010 @@ -41,4 +41,4 @@ module.setlistitem(l, 0) assert len(l) == 1 - raises(TypeError, module.setlistitem, (1, 2, 3), 0) + raises(SystemError, module.setlistitem, (1, 2, 3), 0) From agaynor at codespeak.net Sat Mar 27 22:28:34 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sat, 27 Mar 2010 22:28:34 +0100 (CET) Subject: [pypy-svn] r72985 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327212834.94C2E282B90@codespeak.net> Author: agaynor Date: Sat Mar 27 22:28:32 2010 New Revision: 72985 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Implement Py_XINCREF. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sat Mar 27 22:28:32 2010 @@ -50,6 +50,11 @@ debug_refcount("INCREF", obj, obj.c_obj_refcnt, frame_stackdepth=3) @cpython_api([PyObject], lltype.Void) +def Py_XINCREF(space, obj): + if obj: + Py_INCREF(space, obj) + + at cpython_api([PyObject], lltype.Void) def Py_XDECREF(space, obj): if obj: Py_DECREF(space, obj) From agaynor at codespeak.net Sat Mar 27 22:35:56 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sat, 27 Mar 2010 22:35:56 +0100 (CET) Subject: [pypy-svn] r72986 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327213556.15D9D282B90@codespeak.net> Author: agaynor Date: Sat Mar 27 22:35:54 2010 New Revision: 72986 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Log: Implement PyList_Append. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Sat Mar 27 22:35:54 2010 @@ -36,3 +36,10 @@ "list assignment index out of range")) wrappeditems[index] = w_item return 0 + + at cpython_api([PyObject, PyObject], rffi.INT_real, error=-1) +def PyList_Append(space, w_list, w_item): + if not isinstance(w_list, W_ListObject): + PyErr_BadInternalCall(space) + w_list.append(w_item) + return 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Sat Mar 27 22:35:54 2010 @@ -26,7 +26,14 @@ Py_INCREF(Py_None); return Py_None; """ - ) + ), + ("appendlist", "METH_VARARGS", + """ + PyObject *l = PyTuple_GetItem(args, 0); + PyList_Append(l, PyTuple_GetItem(args, 1)); + Py_RETURN_NONE; + """ + ), ]) l = module.newlist() assert l == [3, -5, 1000] @@ -42,3 +49,9 @@ assert len(l) == 1 raises(SystemError, module.setlistitem, (1, 2, 3), 0) + + l = [] + module.appendlist(l, 14) + assert len(l) == 1 + assert l[0] == 14 + From getxsick at codespeak.net Sat Mar 27 22:49:09 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sat, 27 Mar 2010 22:49:09 +0100 (CET) Subject: [pypy-svn] r72987 - pypy/build/ubuntu/trunk/debian Message-ID: <20100327214909.34F0E282B90@codespeak.net> Author: getxsick Date: Sat Mar 27 22:49:07 2010 New Revision: 72987 Modified: pypy/build/ubuntu/trunk/debian/control Log: update depends Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sat Mar 27 22:49:07 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libsqlite3-dev, libdb4.6 +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 Standards-Version: 3.8.0 Homepage: http://pypy.org From getxsick at codespeak.net Sat Mar 27 23:05:54 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sat, 27 Mar 2010 23:05:54 +0100 (CET) Subject: [pypy-svn] r72988 - in pypy/build/ubuntu: 1.2.0/debian trunk/debian Message-ID: <20100327220554.9AD4A282B90@codespeak.net> Author: getxsick Date: Sat Mar 27 23:05:52 2010 New Revision: 72988 Modified: pypy/build/ubuntu/1.2.0/debian/control pypy/build/ubuntu/trunk/debian/changelog Log: merge changes Modified: pypy/build/ubuntu/1.2.0/debian/control ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/control (original) +++ pypy/build/ubuntu/1.2.0/debian/control Sat Mar 27 23:05:52 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 Standards-Version: 3.8.0 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.6 Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. Modified: pypy/build/ubuntu/trunk/debian/changelog ============================================================================== --- pypy/build/ubuntu/trunk/debian/changelog (original) +++ pypy/build/ubuntu/trunk/debian/changelog Sat Mar 27 23:05:52 2010 @@ -1,3 +1,10 @@ +pypy (1.2.0-4) karmic; urgency=low + + * Add missing build-depends. + * Update distribution to karmic. + + -- Bartosz Skowron Fri, 26 Mar 2010 12:40:31 +0100 + pypy (1.2.0-3) jaunty; urgency=low * New upstream release. From agaynor at codespeak.net Sat Mar 27 23:09:04 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sat, 27 Mar 2010 23:09:04 +0100 (CET) Subject: [pypy-svn] r72989 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100327220904.96490282B90@codespeak.net> Author: agaynor Date: Sat Mar 27 23:09:03 2010 New Revision: 72989 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: Add a backwards compatibility macro. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sat Mar 27 23:09:03 2010 @@ -5,6 +5,13 @@ #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None + +/* +CPyton has this for backwards compatibility with really old extensions, and now +we have it for compatibility with CPython. +*/ +#define staticforward static + typedef void* Py_buffer; From fijal at codespeak.net Sat Mar 27 23:15:29 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 23:15:29 +0100 (CET) Subject: [pypy-svn] r72990 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327221529.53A9B282B90@codespeak.net> Author: fijal Date: Sat Mar 27 23:15:27 2010 New Revision: 72990 Added: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (contents, props changed) pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Log: (zooko, fijal) Start adding a sequence impl Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sat Mar 27 23:15:27 2010 @@ -42,5 +42,6 @@ import pypy.module.cpyext.dictobject import pypy.module.cpyext.intobject import pypy.module.cpyext.listobject +import pypy.module.cpyext.sequence # now that all rffi_platform.Struct types are registered, configure them api.configure_types() Added: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Sat Mar 27 23:15:27 2010 @@ -0,0 +1,19 @@ + +from pypy.interpreter.error import OperationError +from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ + Py_ssize_t +from pypy.rpython.lltypesystem import rffi, lltype + + at cpython_api([PyObject, rffi.CCHARP], PyObject) +def PySequence_Fast(space, w_obj, m): + """Returns the sequence o as a tuple, unless it is already a tuple or list, in + which case o is returned. Use PySequence_Fast_GET_ITEM() to access the + members of the result. Returns NULL on failure. If the object is not a + sequence, raises TypeError with m as the message text.""" + if (space.is_true(space.isinstance(w_obj, space.w_list)) or + space.is_true(space.isinstance(w_obj, space.w_tuple))): + return w_obj + try: + return space.newtuple(space.unpackiterable(w_obj)) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m))) Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Sat Mar 27 23:15:27 2010 @@ -0,0 +1,26 @@ + + +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + +class AppTestIterator(AppTestCpythonExtensionBase): + def test_iterator(self): + import sys + module = self.import_extension('foo', [ + ("newiter", "METH_VARARGS", + ''' + return PySequence_Fast(PyTuple_GetItem(args, 0), "message"); + ''' + ), + ]) + t = (1, 2, 3, 4) + assert module.newiter(t) is t + l = [1, 2, 3, 4] + assert module.newiter(l) is l + assert isinstance(module.newiter(set([1, 2, 3])), tuple) + assert sorted(module.newiter(set([1, 2, 3]))) == [1, 2, 3] + try: + module.newiter(3) + except TypeError, te: + assert te.args == ("message",) + else: + raise Exception("DID NOT RAISE") From zooko at codespeak.net Sat Mar 27 23:23:30 2010 From: zooko at codespeak.net (zooko at codespeak.net) Date: Sat, 27 Mar 2010 23:23:30 +0100 (CET) Subject: [pypy-svn] r72991 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327222330.E4E0E282B90@codespeak.net> Author: zooko Date: Sat Mar 27 23:23:29 2010 New Revision: 72991 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt Log: (zooko, fijal) Add to c-api.txt a statement that PyPy doesn't support the PySequence_Fast_ITEMS() function although it does support the other "fast sequence" functions. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/c-api.txt Sat Mar 27 23:23:29 2010 @@ -49,3 +49,23 @@ - There could be an (expensive!) check in from_ref() that the buffer still corresponds to the pypy gc-managed string. + +PySequence_Fast support +====================== +There are five functions for fast sequence access offered by the CPython API: + +PyObject* PySequence_Fast(PyObject *o, const char *m) + +PyObject* PySequence_Fast_GET_ITEM( PyObject *o, int i) + +PyObject** PySequence_Fast_ITEMS( PyObject *o) + +PyObject* PySequence_ITEM( PyObject *o, int i) + +int PySequence_Fast_GET_SIZE( PyObject *o) + +PyPy supports four of these, but does not support PySequence_Fast_ITEMS. +(Various ways to support PySequence_Fast_ITEMS were considered. They all had +two things in common: they would have taken a lot of work, and they would have +resulted in incomplete semantics or in poor performance. We decided that a slow +implementation of PySequence_Fast_ITEMS was not very useful.) From xoraxax at codespeak.net Sat Mar 27 23:28:05 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 23:28:05 +0100 (CET) Subject: [pypy-svn] r72992 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327222805.2611E282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 23:28:03 2010 New Revision: 72992 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Log: Reorder code in __init__.py. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sat Mar 27 23:28:03 2010 @@ -16,7 +16,7 @@ def setup_after_space_initialization(self): """NOT_RPYTHON""" state = self.space.fromcache(State) - if not we_are_translated(): + if not self.space.config.translating: state.api_lib = str(pypy.module.cpyext.api.build_bridge(self.space)) state.slotdefs = init_slotdefs(self.space) else: @@ -24,9 +24,10 @@ def startup(self, space): state = space.fromcache(State) - space.setattr(space.wrap(self), - space.wrap('api_lib'), - space.wrap(state.api_lib)) + if not we_are_translated(): + space.setattr(space.wrap(self), + space.wrap('api_lib'), + space.wrap(state.api_lib)) # import these modules to register api functions by side-effect import pypy.module.cpyext.boolobject From agaynor at codespeak.net Sat Mar 27 23:29:39 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sat, 27 Mar 2010 23:29:39 +0100 (CET) Subject: [pypy-svn] r72993 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100327222939.DB76D282B90@codespeak.net> Author: agaynor Date: Sat Mar 27 23:29:38 2010 New Revision: 72993 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: Added decleration for the type error object. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sat Mar 27 23:29:38 2010 @@ -385,6 +385,7 @@ PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; +PyAPI_DATA(PyObject *) PyExc_TypeError; /* objimpl.h ----------------------------------------------*/ From xoraxax at codespeak.net Sat Mar 27 23:30:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 23:30:09 +0100 (CET) Subject: [pypy-svn] r72994 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327223009.ECAD4282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 23:30:08 2010 New Revision: 72994 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO Log: Add TODO items. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/TODO ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/TODO (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/TODO Sat Mar 27 23:30:08 2010 @@ -11,6 +11,12 @@ - replace @cpython_api(external=False) by another explicit name: all it does is a lltype function pointer, no C code involved. + + - Generate decl code for global objects. + + - Make code translatable. + + - Implement Members. - refactor management of py_objects_r2w and py_objects_w2r, this can probably be expressed in terms of _PyObject_GC_TRACK macros. From xoraxax at codespeak.net Sat Mar 27 23:33:07 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 23:33:07 +0100 (CET) Subject: [pypy-svn] r72995 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327223307.31347282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 23:33:05 2010 New Revision: 72995 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Removed ctypes usages, fix a comment. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 23:33:05 2010 @@ -277,10 +277,7 @@ py_obj.c_obj_refcnt = 1 pto = make_ref(space, space.type(w_obj)) py_obj.c_obj_type = rffi.cast(PyObject, pto) - # XXX remove this weird casting? - ctypes_obj = ll2ctypes.lltype2ctypes(py_obj) - ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value - py_obj = ll2ctypes.ctypes2lltype(PyObject, ctypes_obj) + ptr = rffi.cast(ADDR, py_obj) py_obj = rffi.cast(PyObject, py_obj) debug_refcount("MAKREF", py_obj, w_obj) state.py_objects_w2r[w_obj] = py_obj @@ -304,8 +301,7 @@ ref = rffi.cast(PyObject, ref) w_str = space.wrap(s) state.py_objects_w2r[w_str] = ref - ctypes_obj = ll2ctypes.lltype2ctypes(ref) - ptr = ctypes.cast(ctypes_obj, ctypes.c_void_p).value + ptr = rffi.cast(ADDR, ref) state.py_objects_r2w[ptr] = w_str return w_str @@ -577,7 +573,7 @@ decref_args = kwargs.pop("decref_args", True) assert not kwargs boxed_args = [] - for arg in args: # XXX ur needed + for arg in args: # XXX UI needed if isinstance(arg, W_Root) or arg is None: boxed_args.append(make_ref(space, arg)) else: From xoraxax at codespeak.net Sat Mar 27 23:40:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sat, 27 Mar 2010 23:40:21 +0100 (CET) Subject: [pypy-svn] r72996 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327224021.E1196282B90@codespeak.net> Author: xoraxax Date: Sat Mar 27 23:40:20 2010 New Revision: 72996 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Move "if rename" check into the loop to declare at least the items using #. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 23:40:20 2010 @@ -444,19 +444,21 @@ """ pypy_rename = [] renamed_symbols = [] - if rename: - for name in export_symbols: - if name.startswith("PyPy"): - renamed_symbols.append(name) - continue - if "#" in name: - deref = "*" - else: - deref = "" - name = name.replace("#", "") - newname = name.replace('Py', 'PyPy') - pypy_rename.append('#define %s %s%s' % (name, deref, newname)) - renamed_symbols.append(newname) + for name in export_symbols: + if name.startswith("PyPy"): + renamed_symbols.append(name) + continue + if "#" in name: + deref = "*" + else: + deref = "" + if not rename: continue + name = name.replace("#", "") + newname = name.replace('Py', 'PyPy') + if not rename: + newname = name + pypy_rename.append('#define %s %s%s' % (name, deref, newname)) + renamed_symbols.append(newname) export_symbols = renamed_symbols pypy_rename_h = udir.join('pypy_rename.h') pypy_rename_h.write('\n'.join(pypy_rename)) From fijal at codespeak.net Sat Mar 27 23:43:39 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 23:43:39 +0100 (CET) Subject: [pypy-svn] r72997 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327224339.CDB50282B90@codespeak.net> Author: fijal Date: Sat Mar 27 23:43:38 2010 New Revision: 72997 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: fix name error Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sat Mar 27 23:43:38 2010 @@ -2,7 +2,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ - ADDR, debug_refcount + ADDR, debug_refcount, DEBUG_REFCOUNT from pypy.module.cpyext.state import State From fijal at codespeak.net Sat Mar 27 23:44:09 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 23:44:09 +0100 (CET) Subject: [pypy-svn] r72998 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327224409.37085282B90@codespeak.net> Author: fijal Date: Sat Mar 27 23:44:07 2010 New Revision: 72998 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Log: (zooko, fijal) Add PySequence_Fast_GET_ITEM Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Sat Mar 27 23:44:07 2010 @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ - Py_ssize_t + Py_ssize_t, register_container from pypy.rpython.lltypesystem import rffi, lltype +from pypy.objspace.std import listobject, tupleobject @cpython_api([PyObject, rffi.CCHARP], PyObject) def PySequence_Fast(space, w_obj, m): @@ -17,3 +18,17 @@ return space.newtuple(space.unpackiterable(w_obj)) except OperationError: raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m))) + + at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) +def PySequence_Fast_GET_ITEM(space, w_obj, index): + """Return the ith element of o, assuming that o was returned by + PySequence_Fast(), o is not NULL, and that i is within bounds. + """ + if isinstance(w_obj, listobject.W_ListObject): + w_res = w_obj.wrappeditems[index] + else: + assert isinstance(w_obj, tupleobject.W_TupleObject) + w_res = w_obj.wrappeditems[index] + register_container(space, w_obj) + return w_res + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sat Mar 27 23:44:07 2010 @@ -5081,23 +5081,6 @@ equivalent to the Python expression tuple(o).""" raise NotImplementedError - at cpython_api([PyObject, rffi.CCHARP], PyObject) -def PySequence_Fast(space, o, m): - """Returns the sequence o as a tuple, unless it is already a tuple or list, in - which case o is returned. Use PySequence_Fast_GET_ITEM() to access the - members of the result. Returns NULL on failure. If the object is not a - sequence, raises TypeError with m as the message text.""" - raise NotImplementedError - - at cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) -def PySequence_Fast_GET_ITEM(space, o, i): - """Return the ith element of o, assuming that o was returned by - PySequence_Fast(), o is not NULL, and that i is within bounds. - - This function used an int type for i. This might require - changes in your code for properly supporting 64-bit systems.""" - raise NotImplementedError - @cpython_api([PyObject], {PyObject**}) def PySequence_Fast_ITEMS(space, o): """Return the underlying array of PyObject pointers. Assumes that o was returned Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Sat Mar 27 23:44:07 2010 @@ -11,6 +11,13 @@ return PySequence_Fast(PyTuple_GetItem(args, 0), "message"); ''' ), + ("fast_getitem", "METH_VARARGS", + ''' + PyObject *lst = PyTuple_GetItem(args, 0); + long index = PyInt_AsLong(PyTuple_GetItem(args, 1)); + return PySequence_Fast_GET_ITEM(lst, index); + ''' + ), ]) t = (1, 2, 3, 4) assert module.newiter(t) is t @@ -24,3 +31,4 @@ assert te.args == ("message",) else: raise Exception("DID NOT RAISE") + assert module.fast_getitem((1, 2, 3), 1) == 2 From fijal at codespeak.net Sat Mar 27 23:49:33 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sat, 27 Mar 2010 23:49:33 +0100 (CET) Subject: [pypy-svn] r72999 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327224933.9B5E9282B90@codespeak.net> Author: fijal Date: Sat Mar 27 23:49:31 2010 New Revision: 72999 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Log: Implement PySequence_Fast_GET_SIZE Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Sat Mar 27 23:49:31 2010 @@ -32,3 +32,15 @@ register_container(space, w_obj) return w_res + at cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL) +def PySequence_Fast_GET_SIZE(space, w_obj): + """Returns the length of o, assuming that o was returned by + PySequence_Fast() and that o is not NULL. The size can also be + gotten by calling PySequence_Size() on o, but + PySequence_Fast_GET_SIZE() is faster because it can assume o is a list + or tuple.""" + if isinstance(w_obj, listobject.W_ListObject): + return len(w_obj.wrappeditems) + assert isinstance(w_obj, tupleobject.W_TupleObject) + return len(w_obj.wrappeditems) + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sat Mar 27 23:49:31 2010 @@ -5105,15 +5105,6 @@ changes in your code for properly supporting 64-bit systems.""" raise NotImplementedError - at cpython_api([PyObject], Py_ssize_t) -def PySequence_Fast_GET_SIZE(space, o): - """Returns the length of o, assuming that o was returned by - PySequence_Fast() and that o is not NULL. The size can also be - gotten by calling PySequence_Size() on o, but - PySequence_Fast_GET_SIZE() is faster because it can assume o is a list - or tuple.""" - raise NotImplementedError - @cpython_api([PyObject], rffi.INT_real) def PySet_Check(space, p): """Return true if p is a set object or an instance of a subtype. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Sat Mar 27 23:49:31 2010 @@ -18,6 +18,12 @@ return PySequence_Fast_GET_ITEM(lst, index); ''' ), + ("fast_getsize", "METH_VARARGS", + ''' + PyObject *lst = PyTuple_GetItem(args, 0); + return PyInt_FromLong(PySequence_Fast_GET_SIZE(lst)); + ''' + ), ]) t = (1, 2, 3, 4) assert module.newiter(t) is t @@ -32,3 +38,4 @@ else: raise Exception("DID NOT RAISE") assert module.fast_getitem((1, 2, 3), 1) == 2 + assert module.fast_getsize([1, 2, 3]) == 3 From fijal at codespeak.net Sun Mar 28 00:06:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 00:06:30 +0100 (CET) Subject: [pypy-svn] r73000 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include Message-ID: <20100327230630.933ED282B90@codespeak.net> Author: fijal Date: Sun Mar 28 00:06:28 2010 New Revision: 73000 Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Log: copy PyModule_AddObject Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c Sun Mar 28 00:06:28 2010 @@ -0,0 +1,31 @@ +#include +#include + +int +PyModule_AddObject(PyObject *m, const char *name, PyObject *o) +{ + PyObject *dict; + if (!PyModule_Check(m)) { + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs module as first arg"); + return -1; + } + if (!o) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, + "PyModule_AddObject() needs non-NULL value"); + return -1; + } + + dict = PyModule_GetDict(m); + if (dict == NULL) { + /* Internal error -- modules must have a dict! */ + PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", + PyModule_GetName(m)); + return -1; + } + if (PyDict_SetItemString(dict, name, o)) + return -1; + Py_DECREF(o); + return 0; +} Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h Sun Mar 28 00:06:28 2010 @@ -18,7 +18,7 @@ Py_InitModule4(name, methods, doc, (PyObject *)NULL, \ PYTHON_API_VERSION) - +int PyModule_AddObject(PyObject *m, const char *name, PyObject *o); #ifdef __cplusplus } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Sun Mar 28 00:06:28 2010 @@ -84,3 +84,4 @@ return w_dict else: PyErr_BadInternalCall(space) + From getxsick at codespeak.net Sun Mar 28 00:15:30 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 00:15:30 +0100 (CET) Subject: [pypy-svn] r73001 - pypy/build/ubuntu/1.2.0/debian Message-ID: <20100327231530.8AA81282B90@codespeak.net> Author: getxsick Date: Sun Mar 28 00:15:29 2010 New Revision: 73001 Modified: pypy/build/ubuntu/1.2.0/debian/rules Log: update get-orig-source for 1.2.0 Modified: pypy/build/ubuntu/1.2.0/debian/rules ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/rules (original) +++ pypy/build/ubuntu/1.2.0/debian/rules Sun Mar 28 00:15:29 2010 @@ -16,7 +16,7 @@ svn co http://codespeak.net/svn/pypy/release/1.2.0 pypy-1.2.0 ; \ REVISION=`svnversion pypy-1.2.0/` ; \ find pypy-1.2.0/ -depth -type d -name ".svn" | xargs rm -rf ; \ - tar cfz pypy_$(VERSION).0-svn$$REVISION.orig.tar.gz pypy-1.2.0/ ; \ + tar cfz pypy_$(VERSION).0.orig.tar.gz pypy-1.2.0/ ; \ rm -rf pypy-1.2.0/ Makefile: debian/Makefile.in From agaynor at codespeak.net Sun Mar 28 00:23:02 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sun, 28 Mar 2010 00:23:02 +0100 (CET) Subject: [pypy-svn] r73002 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327232302.5976B282B90@codespeak.net> Author: agaynor Date: Sun Mar 28 00:23:00 2010 New Revision: 73002 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Log: Implement PyString_Check. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Sun Mar 28 00:23:00 2010 @@ -1,8 +1,18 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \ - PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref + PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref, CANNOT_FAIL, \ + general_check + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyString_Check(space, w_obj): + """Return true if the object o is a string object or an instance of a subtype of + the string type. + + Allowed subtypes to be accepted.""" + w_type = space.w_str + return general_check(space, w_obj, w_type) + @cpython_api([rffi.CCHARP, Py_ssize_t], PyStringObject, error=lltype.nullptr(PyStringObject.TO)) def PyString_FromStringAndSize(space, char_p, length): if char_p: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sun Mar 28 00:23:00 2010 @@ -5274,14 +5274,6 @@ raise NotImplementedError @cpython_api([PyObject], rffi.INT_real) -def PyString_Check(space, o): - """Return true if the object o is a string object or an instance of a subtype of - the string type. - - Allowed subtypes to be accepted.""" - raise NotImplementedError - - at cpython_api([PyObject], rffi.INT_real) def PyString_CheckExact(space, o): """Return true if the object o is a string object, but not an instance of a subtype of the string type. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_stringobject.py Sun Mar 28 00:23:00 2010 @@ -41,11 +41,18 @@ Py_DECREF(f); return NULL; """), + ("test_is_string", "METH_VARARGS", + """ + return PyBool_FromLong(PyString_Check(PyTuple_GetItem(args, 0))); + """), ]) assert module.get_hello1() == 'Hello world' assert module.get_hello2() == 'Hello world' assert module.test_Size() raises(TypeError, module.test_Size_exception) + + assert module.test_is_string("") + assert not module.test_is_string(()) def test_string_buffer_init(self): module = self.import_extension('foo', [ From agaynor at codespeak.net Sun Mar 28 00:31:57 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sun, 28 Mar 2010 00:31:57 +0100 (CET) Subject: [pypy-svn] r73003 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100327233157.B3B3D282B90@codespeak.net> Author: agaynor Date: Sun Mar 28 00:31:56 2010 New Revision: 73003 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Log: Implemented PyNumber_Float. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py Sun Mar 28 00:31:56 2010 @@ -1,5 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject +from pypy.interpreter.error import OperationError @cpython_api([lltype.Float], PyObject) def PyFloat_FromDouble(space, value): @@ -8,3 +9,14 @@ @cpython_api([PyObject], lltype.Float, error=-1) def PyFloat_AsDouble(space, w_obj): return space.float_w(space.float(w_obj)) + + + at cpython_api([PyObject], PyObject) +def PyNumber_Float(space, w_obj): + """ + Returns the o converted to a float object on success, or NULL on failure. + This is the equivalent of the Python expression float(o).""" + try: + return space.float(w_obj) + except OperationError: + return None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Sun Mar 28 00:31:56 2010 @@ -1,4 +1,5 @@ from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestFloatObject(BaseApiTest): def test_floatobject(self, space, api): @@ -7,3 +8,25 @@ assert api.PyFloat_AsDouble(space.w_None) == -1 api.PyErr_Clear() + +class AppTestFloatObject(AppTestCpythonExtensionBase): + def test_float(self): + module = self.import_extension("foo", [ + ("test_float_coerce", "METH_NOARGS", + """ + PyObject *p = PyNumber_Float(PyTuple_GetItem(args, 0)); + if (p != NULL) { + return p; + } + Py_RETURN_NONE; + """), + ]) + + assert type(module.test_float_coerce(3)) is float + assert module.test_float_coerce([]) is None + + class Coerce(object): + def __float__(self): + return 42.5 + + assert module.test_float_coerce(Coerce()) == 42.5 From xoraxax at codespeak.net Sun Mar 28 00:35:00 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 00:35:00 +0100 (CET) Subject: [pypy-svn] r73004 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100327233500.8B293282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 00:34:59 2010 New Revision: 73004 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Always cast the return value in the wrapper. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 00:34:59 2010 @@ -406,8 +406,8 @@ assert False, "Container not registered by %s" % (callable, ) else: raise - elif callable.api_func.restype is rffi.INT_real: - retval = rffi.cast(rffi.INT_real, retval) + elif callable.api_func.restype is not lltype.Void: + retval = rffi.cast(callable.api_func.restype, retval) return retval wrapper.__name__ = "wrapper for %r" % (callable, ) return wrapper From fijal at codespeak.net Sun Mar 28 00:53:30 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 00:53:30 +0100 (CET) Subject: [pypy-svn] r73005 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include Message-ID: <20100327235330.A79EB282B90@codespeak.net> Author: fijal Date: Sun Mar 28 00:53:29 2010 New Revision: 73005 Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: Copy a bit of stuff from CPython and include it in compilation Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 00:53:29 2010 @@ -512,7 +512,9 @@ eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], - separate_module_files=[include_dir / "varargwrapper.c"], + separate_module_files=[include_dir / "varargwrapper.c", + include_dir / "pyerrors.c", + include_dir / "modsupport.c"], export_symbols=['pypyAPI'] + export_symbols, ) eci = eci.convert_sources_to_files() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sun Mar 28 00:53:29 2010 @@ -386,6 +386,7 @@ PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; PyAPI_DATA(PyObject *) PyExc_TypeError; +PyAPI_DATA(PyObject *) PyExc_SystemError; /* objimpl.h ----------------------------------------------*/ Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c Sun Mar 28 00:53:29 2010 @@ -0,0 +1,54 @@ + +#include +#include +#include + +PyObject * +PyErr_NewException(char *name, PyObject *base, PyObject *dict) +{ + char *dot; + PyObject *modulename = NULL; + PyObject *classname = NULL; + PyObject *mydict = NULL; + PyObject *bases = NULL; + PyObject *result = NULL; + dot = strrchr(name, '.'); + if (dot == NULL) { + PyErr_SetString(PyExc_SystemError, + "PyErr_NewException: name must be module.class"); + return NULL; + } + if (base == NULL) + base = PyExc_Exception; + if (dict == NULL) { + dict = mydict = PyDict_New(); + if (dict == NULL) + goto failure; + } + if (PyDict_GetItemString(dict, "__module__") == NULL) { + modulename = PyString_FromStringAndSize(name, + (Py_ssize_t)(dot-name)); + if (modulename == NULL) + goto failure; + if (PyDict_SetItemString(dict, "__module__", modulename) != 0) + goto failure; + } + if (PyTuple_Check(base)) { + bases = base; + /* INCREF as we create a new ref in the else branch */ + Py_INCREF(bases); + } else { + bases = PyTuple_Pack(1, base); + if (bases == NULL) + goto failure; + } + /* Create a real new-style class. */ + result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO", + dot+1, bases, dict); + failure: + Py_XDECREF(bases); + Py_XDECREF(mydict); + Py_XDECREF(classname); + Py_XDECREF(modulename); + return result; +} From fijal at codespeak.net Sun Mar 28 01:07:02 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 01:07:02 +0100 (CET) Subject: [pypy-svn] r73006 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100328000702.D12A2282B90@codespeak.net> Author: fijal Date: Sun Mar 28 01:07:01 2010 New Revision: 73006 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Log: A prototype Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Sun Mar 28 01:07:01 2010 @@ -7,6 +7,8 @@ extern "C" { #endif +PyObject *PyErr_NewException(char *name, PyObject *base, PyObject *dict); + PyAPI_DATA(PyObject *) PyExc_Exception; #ifdef __cplusplus From fijal at codespeak.net Sun Mar 28 01:07:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 01:07:36 +0100 (CET) Subject: [pypy-svn] r73007 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100328000736.75A14282B90@codespeak.net> Author: fijal Date: Sun Mar 28 01:07:34 2010 New Revision: 73007 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Log: Implement PyDict_GetItemString Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Sun Mar 28 01:07:34 2010 @@ -1,7 +1,8 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \ - general_check + general_check, register_container from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall +from pypy.interpreter.error import OperationError @cpython_api([], PyObject) def PyDict_New(space): @@ -37,3 +38,15 @@ return 0 else: PyErr_BadInternalCall(space) + + at cpython_api([PyObject, rffi.CCHARP], PyObject, borrowed=True) +def PyDict_GetItemString(space, w_dict, key): + """This is the same as PyDict_GetItem(), but key is specified as a + char*, rather than a PyObject*.""" + if not PyDict_Check(space, w_dict): + PyErr_BadInternalCall(space) + w_res = space.finditem_str(w_dict, rffi.charp2str(key)) + if w_res is None: + raise OperationError(space.w_KeyError, space.wrap("Key not found")) + register_container(space, w_dict) + return w_res Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Sun Mar 28 01:07:34 2010 @@ -1388,12 +1388,6 @@ if the key key is not present, but without setting an exception.""" raise NotImplementedError - at cpython_api([PyObject, rffi.CCHARP], PyObject, borrowed=True) -def PyDict_GetItemString(space, p, key): - """This is the same as PyDict_GetItem(), but key is specified as a - char*, rather than a PyObject*.""" - raise NotImplementedError - @cpython_api([PyObject], PyObject) def PyDict_Items(space, p): """Return a PyListObject containing all the items from the Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Sun Mar 28 01:07:34 2010 @@ -22,6 +22,11 @@ ); Py_RETURN_NONE; """), + ("dict_getitem_str", "METH_VARARGS", + """ + return PyDict_GetItemString(PyTuple_GetItem(args, 0), "name"); + """ + ), ]) assert module.test_dict_create() == {} @@ -29,3 +34,7 @@ d = {} module.test_dict_setitem(d, "c", 72) assert d["c"] == 72 + d["name"] = 3 + assert module.dict_getitem_str(d) == 3 + del d["name"] + raises(KeyError, module.dict_getitem_str, d) From agaynor at codespeak.net Sun Mar 28 01:12:20 2010 From: agaynor at codespeak.net (agaynor at codespeak.net) Date: Sun, 28 Mar 2010 01:12:20 +0100 (CET) Subject: [pypy-svn] r73008 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100328001220.92DBA282B90@codespeak.net> Author: agaynor Date: Sun Mar 28 01:12:19 2010 New Revision: 73008 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Log: Fix PyNumber_Float, its semantics are documented confusingly. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/floatobject.py Sun Mar 28 01:12:19 2010 @@ -16,7 +16,4 @@ """ Returns the o converted to a float object on success, or NULL on failure. This is the equivalent of the Python expression float(o).""" - try: - return space.float(w_obj) - except OperationError: - return None + return space.float(w_obj) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Sun Mar 28 01:12:19 2010 @@ -14,16 +14,12 @@ module = self.import_extension("foo", [ ("test_float_coerce", "METH_NOARGS", """ - PyObject *p = PyNumber_Float(PyTuple_GetItem(args, 0)); - if (p != NULL) { - return p; - } - Py_RETURN_NONE; + return PyNumber_Float(PyTuple_GetItem(args, 0)); """), ]) assert type(module.test_float_coerce(3)) is float - assert module.test_float_coerce([]) is None + raises(TypeError, module.test_float_coerce, None) class Coerce(object): def __float__(self): From xoraxax at codespeak.net Sun Mar 28 01:44:38 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 01:44:38 +0100 (CET) Subject: [pypy-svn] r73009 - in pypy/branch/cpython-extension/pypy: config rlib translator translator/c translator/c/test Message-ID: <20100328004438.D3F25282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 01:44:37 2010 New Revision: 73009 Added: pypy/branch/cpython-extension/pypy/rlib/entrypoint.py (contents, props changed) Modified: pypy/branch/cpython-extension/pypy/config/translationoption.py pypy/branch/cpython-extension/pypy/translator/c/genc.py pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py pypy/branch/cpython-extension/pypy/translator/driver.py Log: Implement support for secondary entrypoints. Modified: pypy/branch/cpython-extension/pypy/config/translationoption.py ============================================================================== --- pypy/branch/cpython-extension/pypy/config/translationoption.py (original) +++ pypy/branch/cpython-extension/pypy/config/translationoption.py Sun Mar 28 01:44:37 2010 @@ -138,6 +138,9 @@ ArbitraryOption("instrumentctl", "internal", default=None), StrOption("output", "Output file name", cmdline="--output"), + StrOption("secondaryentrypoints", + "Comma separated list of keys choosing secondary entrypoints", + cmdline="--entrypoints", default=""), BoolOption("dump_static_data_info", "Dump static data info", cmdline="--dump_static_data_info", Added: pypy/branch/cpython-extension/pypy/rlib/entrypoint.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/rlib/entrypoint.py Sun Mar 28 01:44:37 2010 @@ -0,0 +1,11 @@ +secondary_entrypoints = {} + + +def entrypoint(key, argtypes, c_name=None): + def deco(func): + secondary_entrypoints.setdefault(key, []).append((func, argtypes)) + if c_name is not None: + func.c_name = c_name + return func + return deco + Modified: pypy/branch/cpython-extension/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/genc.py Sun Mar 28 01:44:37 2010 @@ -103,7 +103,8 @@ modulename = None split = False - def __init__(self, translator, entrypoint, config, gcpolicy=None): + def __init__(self, translator, entrypoint, config, gcpolicy=None, + secondary_entrypoints=()): self.translator = translator self.entrypoint = entrypoint self.entrypoint_name = getattr(self.entrypoint, 'func_name', None) @@ -113,6 +114,7 @@ if gcpolicy is not None and gcpolicy.requires_stackless: config.translation.stackless = True self.eci = self.get_eci() + self.secondary_entrypoints = secondary_entrypoints def get_eci(self): pypy_include_dir = py.path.local(autopath.pypydir).join('translator', 'c') @@ -159,6 +161,11 @@ self.c_entrypoint_name = None else: pfname = db.get(pf) + + for func, _ in self.secondary_entrypoints: + bk = translator.annotator.bookkeeper + db.get(getfunctionptr(bk.getdesc(func).getuniquegraph())) + self.c_entrypoint_name = pfname db.complete() Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Sun Mar 28 01:44:37 2010 @@ -12,6 +12,7 @@ from pypy.translator.gensupp import uniquemodulename from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.interactive import Translation +from pypy.rlib.entrypoint import entrypoint def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True, annotatorpolicy=None): @@ -396,3 +397,20 @@ if py.test.config.option.view: t.view() assert 'pypy_xyz_f' in t.driver.cbuilder.c_source_filename.read() + +def test_entrypoints(): + def f(): + return 3 + + key = "test_entrypoints42" + @entrypoint(key, [int], "foobar") + def g(x): + return x + 42 + + t = Translation(f, [], backend="c", secondaryentrypoints="test_entrypoints42") + t.annotate() + compiled_fn = t.compile_c() + if py.test.config.option.view: + t.view() + assert 'foobar' in t.driver.cbuilder.c_source_filename.read() + Modified: pypy/branch/cpython-extension/pypy/translator/driver.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/driver.py (original) +++ pypy/branch/cpython-extension/pypy/translator/driver.py Sun Mar 28 01:44:37 2010 @@ -12,6 +12,7 @@ import optparse from pypy.tool.udir import udir from pypy.rlib.jit import DEBUG_OFF, DEBUG_DETAILED, DEBUG_PROFILE, DEBUG_STEPS +from pypy.rlib.entrypoint import secondary_entrypoints import py from pypy.tool.ansi_print import ansi_log @@ -210,12 +211,22 @@ self.entry_point = entry_point self.translator = translator self.libdef = None + self.secondary_entrypoints = [] + for key in self.config.translation.secondaryentrypoints.split(","): + try: + points = secondary_entrypoints[key] + except KeyError: + raise KeyError("Entrypoints not found. I only know the keys %r." % + (", ".join(secondary_entrypoints.keys()), )) + self.secondary_entrypoints.extend(points) self.translator.driver_instrument_result = self.instrument_result def setup_library(self, libdef, policy=None, extra={}, empty_translator=None): + """ Used by carbon python only. """ self.setup(None, None, policy, extra, empty_translator) self.libdef = libdef + self.secondary_entrypoints = libdef.functions def instrument_result(self, args): backend, ts = self.get_backend_and_type_system() @@ -305,20 +316,21 @@ if self.entry_point: s = annotator.build_types(self.entry_point, self.inputtypes) - self.sanity_check_annotation() - if self.standalone and s.knowntype != int: - raise Exception("stand-alone program entry point must return an " - "int (and not, e.g., None or always raise an " - "exception).") - annotator.simplify() - return s else: - assert self.libdef is not None - for func, inputtypes in self.libdef.functions: - annotator.build_types(func, inputtypes) - func.c_name = func.func_name - self.sanity_check_annotation() - annotator.simplify() + s = None + if self.secondary_entrypoints is not None: + for func, inputtypes in self.secondary_entrypoints: + if inputtypes == Ellipsis: + continue + rettype = annotator.build_types(func, inputtypes) + + self.sanity_check_annotation() + if self.entry_point and self.standalone and s.knowntype != int: + raise Exception("stand-alone program entry point must return an " + "int (and not, e.g., None or always raise an " + "exception).") + annotator.simplify() + # task_annotate = taskdef(task_annotate, [], "Annotating&simplifying") @@ -453,7 +465,8 @@ else: from pypy.translator.c.genc import CExtModuleBuilder as CBuilder cbuilder = CBuilder(self.translator, self.entry_point, - config=self.config) + config=self.config, + secondary_entrypoints=self.secondary_entrypoints) cbuilder.stackless = self.config.translation.stackless if not standalone: # xxx more messy cbuilder.modulename = self.extmod_name From xoraxax at codespeak.net Sun Mar 28 03:20:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 03:20:20 +0200 (CEST) Subject: [pypy-svn] r73010 - pypy/trunk/pypy/rpython/lltypesystem/test Message-ID: <20100328012020.15142282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 03:20:19 2010 New Revision: 73010 Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Log: This test fails on pypy, please fix, pretty annoying. Modified: pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/trunk/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Sun Mar 28 03:20:19 2010 @@ -1041,6 +1041,10 @@ #assert lltype.cast_ptr_to_int(ref1) == intval + def test_ptr_truth(self): + abc = rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Void)), 0) + assert not abc + def test_mixed_gcref_comparison(self): NODE = lltype.GcStruct('NODE') node = lltype.malloc(NODE) From xoraxax at codespeak.net Sun Mar 28 03:26:29 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 03:26:29 +0200 (CEST) Subject: [pypy-svn] r73011 - pypy/branch/cpython-extension/pypy/translator Message-ID: <20100328012629.3CC9D282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 03:26:27 2010 New Revision: 73011 Modified: pypy/branch/cpython-extension/pypy/translator/driver.py Log: Annotate secondary entrypoints first because they should be analyzable faster. Modified: pypy/branch/cpython-extension/pypy/translator/driver.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/driver.py (original) +++ pypy/branch/cpython-extension/pypy/translator/driver.py Sun Mar 28 03:26:27 2010 @@ -313,17 +313,17 @@ annmodel.DEBUG = self.config.translation.debug annotator = translator.buildannotator(policy=policy) - if self.entry_point: - s = annotator.build_types(self.entry_point, self.inputtypes) - - else: - s = None if self.secondary_entrypoints is not None: for func, inputtypes in self.secondary_entrypoints: if inputtypes == Ellipsis: continue rettype = annotator.build_types(func, inputtypes) + if self.entry_point: + s = annotator.build_types(self.entry_point, self.inputtypes) + else: + s = None + self.sanity_check_annotation() if self.entry_point and self.standalone and s.knowntype != int: raise Exception("stand-alone program entry point must return an " From xoraxax at codespeak.net Sun Mar 28 03:29:19 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 03:29:19 +0200 (CEST) Subject: [pypy-svn] r73012 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100328012919.65669282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 03:29:17 2010 New Revision: 73012 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: First steps towards a translated cpyext. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Sun Mar 28 03:29:17 2010 @@ -1,8 +1,8 @@ from pypy.interpreter.mixedmodule import MixedModule from pypy.rlib.objectmodel import we_are_translated -import pypy.module.cpyext.api from pypy.module.cpyext.state import State from pypy.module.cpyext.slotdefs import init_slotdefs +from pypy.module.cpyext import api class Module(MixedModule): @@ -17,10 +17,10 @@ """NOT_RPYTHON""" state = self.space.fromcache(State) if not self.space.config.translating: - state.api_lib = str(pypy.module.cpyext.api.build_bridge(self.space)) + state.api_lib = str(api.build_bridge(self.space)) state.slotdefs = init_slotdefs(self.space) else: - XXX # build an import library when translating pypy. + api.setup_library(self.space) def startup(self, space): state = space.fromcache(State) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 03:29:17 2010 @@ -18,6 +18,7 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, unwrap_spec from pypy.objspace.std.stringobject import W_StringObject +from pypy.rlib.entrypoint import entrypoint # CPython 2.4 compatibility from py.builtin import BaseException @@ -99,6 +100,13 @@ self._llhelper = llh return llh + def get_wrapper(self, space): + wrapper = getattr(self, '_wrapper', None) + if wrapper is None: + wrapper = make_wrapper(space, self.callable) + self._wrapper = wrapper + return wrapper + def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True): if error is _NOT_SPECIFIED: if restype is PyObject: @@ -547,12 +555,17 @@ return modulename.new(ext='') +def setup_library(space): + for name, func in FUNCTIONS.iteritems(): + deco = entrypoint("cpyext", func.argtypes, name) + deco(func.get_wrapper(space)) + @unwrap_spec(ObjSpace, str, str) def load_extension_module(space, path, name): state = space.fromcache(State) from pypy.rlib import libffi try: - dll = libffi.CDLL(path) + dll = libffi.CDLL(path, False) except libffi.DLOpenError, e: raise operationerrfmt( space.w_ImportError, @@ -566,7 +579,6 @@ space.w_ImportError, "function init%s not found in library %s", name, path) - dll.unload_on_finalization = False initfunc.call(lltype.Void) state.check_and_raise_exception() From fijal at codespeak.net Sun Mar 28 03:37:04 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 03:37:04 +0200 (CEST) Subject: [pypy-svn] r73013 - in pypy/trunk/pypy/lib: _ctypes app_test/ctypes_tests Message-ID: <20100328013704.D07C1282B90@codespeak.net> Author: fijal Date: Sun Mar 28 03:37:03 2010 New Revision: 73013 Modified: pypy/trunk/pypy/lib/_ctypes/function.py pypy/trunk/pypy/lib/app_test/ctypes_tests/test_cast.py Log: A test and a fix Modified: pypy/trunk/pypy/lib/_ctypes/function.py ============================================================================== --- pypy/trunk/pypy/lib/_ctypes/function.py (original) +++ pypy/trunk/pypy/lib/_ctypes/function.py Sun Mar 28 03:37:03 2010 @@ -359,6 +359,9 @@ # No output parameter, return the actual function result. return retval + def __nonzero__(self): + return bool(self._buffer[0]) + def __del__(self): if self._needs_free: # XXX we need to find a bad guy here Modified: pypy/trunk/pypy/lib/app_test/ctypes_tests/test_cast.py ============================================================================== --- pypy/trunk/pypy/lib/app_test/ctypes_tests/test_cast.py (original) +++ pypy/trunk/pypy/lib/app_test/ctypes_tests/test_cast.py Sun Mar 28 03:37:03 2010 @@ -84,4 +84,6 @@ my_sqrt = lib.my_sqrt sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double)) assert sqrt(4.0) == 2.0 + assert not cast(0, CFUNCTYPE(c_int)) + From xoraxax at codespeak.net Sun Mar 28 03:40:10 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 03:40:10 +0200 (CEST) Subject: [pypy-svn] r73014 - pypy/branch/cpython-extension/pypy/config Message-ID: <20100328014010.A5839282B90@codespeak.net> Author: xoraxax Date: Sun Mar 28 03:40:09 2010 New Revision: 73014 Modified: pypy/branch/cpython-extension/pypy/config/pypyoption.py Log: Add cpyext to the allmodules list. Modified: pypy/branch/cpython-extension/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/cpython-extension/pypy/config/pypyoption.py (original) +++ pypy/branch/cpython-extension/pypy/config/pypyoption.py Sun Mar 28 03:40:09 2010 @@ -29,7 +29,7 @@ "rctime" , "select", "zipimport", "_lsprof", "crypt", "signal", "_rawffi", "termios", "zlib", "struct", "md5", "sha", "bz2", "_minimal_curses", "cStringIO", - "thread", "itertools", "pyexpat", "_ssl"] + "thread", "itertools", "pyexpat", "_ssl", "cpyext"] )) working_oo_modules = default_modules.copy() @@ -66,6 +66,7 @@ # itself needs the interp-level struct module # because 'P' is missing from the app-level one '_rawffi': [("objspace.usemodules.struct", True)], + 'cpyext': [("translation.secondaryentrypoints", "cpyext")], } module_import_dependencies = { From xoraxax at codespeak.net Sun Mar 28 03:55:46 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 03:55:46 +0200 (CEST) Subject: [pypy-svn] r73015 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100328015546.77637282BAD@codespeak.net> Author: xoraxax Date: Sun Mar 28 03:55:44 2010 New Revision: 73015 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Try with a tuple, fails unfortunately as well. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 03:55:44 2010 @@ -557,7 +557,7 @@ def setup_library(space): for name, func in FUNCTIONS.iteritems(): - deco = entrypoint("cpyext", func.argtypes, name) + deco = entrypoint("cpyext", (tuple(func.argtypes), ), name) deco(func.get_wrapper(space)) @unwrap_spec(ObjSpace, str, str) From fijal at codespeak.net Sun Mar 28 04:57:08 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 04:57:08 +0200 (CEST) Subject: [pypy-svn] r73016 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100328025708.461DA282B90@codespeak.net> Author: fijal Date: Sun Mar 28 04:57:03 2010 New Revision: 73016 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Rename obj_* to ob_* to preserve CPython naming. I think this is needed for some extensions, not sure how to avoid that. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 04:57:03 2010 @@ -201,8 +201,8 @@ # So we need a forward and backward mapping in our State instance PyObjectStruct = lltype.ForwardReference() PyObject = lltype.Ptr(PyObjectStruct) -PyObjectFields = (("obj_refcnt", lltype.Signed), ("obj_type", PyObject)) -PyVarObjectFields = PyObjectFields + (("obj_size", Py_ssize_t), ) +PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyObject)) +PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) PyStringObjectStruct = lltype.ForwardReference() @@ -260,7 +260,7 @@ w_type = space.type(w_obj) if space.is_w(w_type, space.w_type): py_obj = allocate_type_obj(space, w_obj) - # c_obj_type and c_obj_refcnt are set by allocate_type_obj + # c_ob_type and c_ob_refcnt are set by allocate_type_obj elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) assert isinstance(w_type, W_PyCTypeObject) @@ -270,21 +270,21 @@ basicsize = pto._obj.c_tp_basicsize T = get_padded_type(PyObject.TO, basicsize) py_obj = lltype.malloc(T, None, flavor="raw", zero=True) - py_obj.c_obj_refcnt = 1 - py_obj.c_obj_type = rffi.cast(PyObject, pto) + py_obj.c_ob_refcnt = 1 + py_obj.c_ob_type = rffi.cast(PyObject, pto) elif isinstance(w_obj, W_StringObject): py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw', zero=True) py_obj.c_size = len(space.str_w(w_obj)) py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) py_obj = rffi.cast(PyObject, py_obj) - py_obj.c_obj_refcnt = 1 - py_obj.c_obj_type = rffi.cast(PyObject, pto) + py_obj.c_ob_refcnt = 1 + py_obj.c_ob_type = rffi.cast(PyObject, pto) else: py_obj = lltype.malloc(PyObject.TO, None, flavor="raw", zero=True) - py_obj.c_obj_refcnt = 1 + py_obj.c_ob_refcnt = 1 pto = make_ref(space, space.type(w_obj)) - py_obj.c_obj_type = rffi.cast(PyObject, pto) + py_obj.c_ob_type = rffi.cast(PyObject, pto) ptr = rffi.cast(ADDR, py_obj) py_obj = rffi.cast(PyObject, py_obj) debug_refcount("MAKREF", py_obj, w_obj) @@ -322,7 +322,7 @@ try: obj = state.py_objects_r2w[ptr] except KeyError: - ref_type = ref.c_obj_type + ref_type = ref.c_ob_type if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str): return force_string(space, ref) else: @@ -428,8 +428,8 @@ object_pto = make_ref(space, space.w_object) object_pto = rffi.cast(PyTypeObjectPtr, object_pto) type_pto.c_tp_base = object_pto - type_pto.c_obj_type = make_ref(space, space.w_type) - object_pto.c_obj_type = make_ref(space, space.w_type) + type_pto.c_ob_type = make_ref(space, space.w_type) + object_pto.c_ob_type = make_ref(space, space.w_type) PyPyType_Ready(space, object_pto, space.w_object) PyPyType_Ready(space, type_pto, space.w_type) type_pto.c_tp_bases = make_ref(space, space.newtuple([space.w_object])) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sun Mar 28 04:57:03 2010 @@ -16,12 +16,12 @@ #define PyObject_HEAD \ - long obj_refcnt; \ - struct _object *obj_type; + long ob_refcnt; \ + struct _object *ob_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ - Py_ssize_t obj_size; /* Number of items in variable part */ + Py_ssize_t ob_size; /* Number of items in variable part */ #define PyObject_HEAD_INIT(type) \ 1, type, @@ -37,9 +37,9 @@ PyObject_VAR_HEAD } PyVarObject; -#define Py_REFCNT(ob) (((PyObject*)(ob))->obj_refcnt) -#define Py_TYPE(ob) (((PyObject*)(ob))->obj_type) -#define Py_SIZE(ob) (((PyVarObject*)(ob))->obj_size) +#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) struct _typeobject; Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sun Mar 28 04:57:03 2010 @@ -10,13 +10,13 @@ @cpython_api([PyObject], lltype.Void) def Py_DECREF(space, obj): from pypy.module.cpyext.typeobject import string_dealloc - obj.c_obj_refcnt -= 1 - debug_refcount("DECREF", obj, obj.c_obj_refcnt, frame_stackdepth=3) - if obj.c_obj_refcnt == 0: + obj.c_ob_refcnt -= 1 + debug_refcount("DECREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) + if obj.c_ob_refcnt == 0: state = space.fromcache(State) ptr = rffi.cast(ADDR, obj) if ptr not in state.py_objects_r2w and \ - space.is_w(from_ref(space, obj.c_obj_type), space.w_str): + space.is_w(from_ref(space, obj.c_ob_type), space.w_str): # this is a half-allocated string, lets call the deallocator # without modifying the r2w/w2r dicts _Py_Dealloc(space, obj) @@ -41,13 +41,13 @@ hex(containee) del state.borrow_mapping[ptr] else: - assert obj.c_obj_refcnt > 0 + assert obj.c_ob_refcnt > 0 @cpython_api([PyObject], lltype.Void) def Py_INCREF(space, obj): - obj.c_obj_refcnt += 1 - assert obj.c_obj_refcnt > 0 - debug_refcount("INCREF", obj, obj.c_obj_refcnt, frame_stackdepth=3) + obj.c_ob_refcnt += 1 + assert obj.c_ob_refcnt > 0 + debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) @cpython_api([PyObject], lltype.Void) def Py_XINCREF(space, obj): @@ -62,7 +62,7 @@ def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr from pypy.module.cpyext.methodobject import generic_cpy_call - pto = obj.c_obj_type + pto = obj.c_ob_type pto = rffi.cast(PyTypeObjectPtr, pto) #print >>sys.stderr, "Calling dealloc slot of", obj, \ # "'s type which is", rffi.charp2str(pto.c_tp_name) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Sun Mar 28 04:57:03 2010 @@ -21,7 +21,7 @@ @cpython_api([PyObject], lltype.Void) def PyObject_dealloc(space, obj): - pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) obj_voidp = rffi.cast(rffi.VOIDP_real, obj) generic_cpy_call(space, pto.c_tp_free, obj_voidp) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Sun Mar 28 04:57:03 2010 @@ -49,4 +49,4 @@ def print_refcounts(self): print "REFCOUNTS" for w_obj, obj in self.py_objects_w2r.items(): - print "%r: %i" % (w_obj, obj.c_obj_refcnt) + print "%r: %i" % (w_obj, obj.c_ob_refcnt) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Sun Mar 28 04:57:03 2010 @@ -21,13 +21,13 @@ return rffi.cast(PyStringObject, ptr) else: py_str = lltype.malloc(PyStringObject.TO, None, flavor='raw') - py_str.c_obj_refcnt = 1 + py_str.c_ob_refcnt = 1 buflen = length + 1 py_str.c_buffer = lltype.malloc(rffi.CCHARP.TO, buflen, flavor='raw') py_str.c_buffer[buflen-1] = '\0' py_str.c_size = length - py_str.c_obj_type = make_ref(space, space.w_str) + py_str.c_ob_type = make_ref(space, space.w_str) return py_str @@ -48,7 +48,7 @@ @cpython_api([PyObject], Py_ssize_t, error=-1) def PyString_Size(space, ref): - if from_ref(space, ref.c_obj_type) is space.w_str: + if from_ref(space, ref.c_ob_type) is space.w_str: ref = rffi.cast(PyStringObject, ref) return ref.c_size else: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Sun Mar 28 04:57:03 2010 @@ -140,7 +140,7 @@ state = self.space.fromcache(State) self.frozen_refcounts = {} for w_obj, obj in state.py_objects_w2r.iteritems(): - self.frozen_refcounts[w_obj] = obj.c_obj_refcnt + self.frozen_refcounts[w_obj] = obj.c_ob_refcnt state.print_refcounts() def check_and_print_leaks(self): @@ -151,7 +151,7 @@ lost_objects_w.update((key, None) for key in self.frozen_refcounts.keys()) for w_obj, obj in state.py_objects_w2r.iteritems(): base_refcnt = self.frozen_refcounts.get(w_obj) - delta = obj.c_obj_refcnt + delta = obj.c_ob_refcnt if base_refcnt is not None: delta -= base_refcnt lost_objects_w.pop(w_obj) @@ -437,4 +437,15 @@ # No exception set, but NULL returned raises(SystemError, module.clear) - + def test_new_exception(self): + skip("not working yet") + mod = self.import_extension('foo', [ + ('newexc', 'METHOD_VARARGS', + ''' + char *name = PyString_AsString(PyTuple_GetItem(args, 0)); + return PyExc_NewException(name, PyTuple_GetItem(args, 1), + PyTuple_GetItem(args, 2)); + ''' + ), + ]) + raises(SystemError, mod.newexc, "name", Exception, {}) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sun Mar 28 04:57:03 2010 @@ -110,7 +110,7 @@ @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): - pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto this_func_ptr = subtype_dealloc.api_func.get_llhelper(space) @@ -129,7 +129,7 @@ @cpython_api([PyObject], lltype.Void, external=False) def string_dealloc(space, obj): obj = rffi.cast(PyStringObject, obj) - pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) if obj.c_buffer: lltype.free(obj.c_buffer, flavor="raw") obj_voidp = rffi.cast(rffi.VOIDP_real, obj) @@ -141,7 +141,7 @@ def type_dealloc(space, obj): state = space.fromcache(State) obj_pto = rffi.cast(PyTypeObjectPtr, obj) - type_pto = rffi.cast(PyTypeObjectPtr, obj.c_obj_type) + type_pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) Py_XDECREF(space, base_pyo) Py_XDECREF(space, obj_pto.c_tp_bases) @@ -162,7 +162,7 @@ assert isinstance(w_type, W_TypeObject) pto = lltype.malloc(PyTypeObject, None, flavor="raw", zero=True) - pto.c_obj_refcnt = 1 + pto.c_ob_refcnt = 1 # put the type object early into the dict # to support dependency cycles like object/type state = space.fromcache(State) @@ -194,10 +194,10 @@ if bases_w: ref = make_ref(space, bases_w[0]) pto.c_tp_base = rffi.cast(PyTypeObjectPtr, ref) - pto.c_obj_type = make_ref(space, space.type(space.w_type)) + pto.c_ob_type = make_ref(space, space.type(space.w_type)) PyPyType_Ready(space, pto, w_type) else: - pto.c_obj_type = lltype.nullptr(PyObject.TO) + pto.c_ob_type = lltype.nullptr(PyObject.TO) # XXX fill slots in pto # would look like fixup_slot_dispatchers() @@ -221,8 +221,8 @@ base = pto.c_tp_base = rffi.cast(PyTypeObjectPtr, base_pyo) if base and not base.c_tp_flags & Py_TPFLAGS_READY: PyPyType_Ready(space, base, None) - if base and not pto.c_obj_type: # will be filled later - pto.c_obj_type = base.c_obj_type + if base and not pto.c_ob_type: # will be filled later + pto.c_ob_type = base.c_ob_type if not pto.c_tp_bases and not (space.is_w(w_obj, space.w_object) or space.is_w(w_obj, space.w_type)): if not base: From fijal at codespeak.net Sun Mar 28 05:00:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 05:00:22 +0200 (CEST) Subject: [pypy-svn] r73017 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100328030022.4024C282B90@codespeak.net> Author: fijal Date: Sun Mar 28 05:00:20 2010 New Revision: 73017 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Log: include string.h Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Sun Mar 28 05:00:20 2010 @@ -25,6 +25,7 @@ #include +#include #include "boolobject.h" #include "floatobject.h" From fijal at codespeak.net Sun Mar 28 05:00:36 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 05:00:36 +0200 (CEST) Subject: [pypy-svn] r73018 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100328030036.D0EB8282B90@codespeak.net> Author: fijal Date: Sun Mar 28 05:00:35 2010 New Revision: 73018 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: The type can only be _typeobject Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Sun Mar 28 05:00:35 2010 @@ -17,7 +17,7 @@ #define PyObject_HEAD \ long ob_refcnt; \ - struct _object *ob_type; + struct _typeobject *ob_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ From fijal at codespeak.net Sun Mar 28 05:33:26 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Sun, 28 Mar 2010 05:33:26 +0200 (CEST) Subject: [pypy-svn] r73019 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100328033326.46219282B90@codespeak.net> Author: fijal Date: Sun Mar 28 05:33:23 2010 New Revision: 73019 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Log: include assert.h as well Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Sun Mar 28 05:33:23 2010 @@ -26,6 +26,7 @@ #include #include +#include #include "boolobject.h" #include "floatobject.h" From getxsick at codespeak.net Sun Mar 28 16:13:16 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:13:16 +0200 (CEST) Subject: [pypy-svn] r73020 - pypy/build/ubuntu/trunk Message-ID: <20100328141316.D776C282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 16:13:14 2010 New Revision: 73020 Added: pypy/build/ubuntu/trunk/autobuild.sh (contents, props changed) Log: add autobuild script (not finished yet) Added: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- (empty file) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:13:14 2010 @@ -0,0 +1,33 @@ +#!/bin/sh +# +# Build pypy trunk PPA package and upload it +# + +LOGFILE="autobuild.log" +( +echo "Start a new build at `date -R`" + +# svn co - trunk/ +svn co http://codespeak.net/svn/pypy/trunk pypy-svn +REVISION=`svnversion pypy-svn/` +find pypy-svn/ -depth -type d -name ".svn" -delete +mv pypy-svn pypy-svn$REVISION + +# create orig +tar cfz pypy_svn$REVISION.orig.tar.gz pypy-svn$REVISION/ + +# svn co - debian/ +svn co http://codespeak.net/svn/pypy/build/ubuntu/trunk/debian +find debian/ -depth -type d -name ".svn" -delete +mv debian/ pypy-svn$REVISION + +# update changelog +dch --newversion svn$REVISION-1 Auto build from trunk + +# build a package +debuild -S -sa + +# upload + +echo "Finish the new build at `date -R`" +) >>$LOGFILE From getxsick at codespeak.net Sun Mar 28 16:19:17 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:19:17 +0200 (CEST) Subject: [pypy-svn] r73021 - pypy/build/ubuntu/trunk Message-ID: <20100328141917.E1EC3282BF0@codespeak.net> Author: getxsick Date: Sun Mar 28 16:19:16 2010 New Revision: 73021 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: disable saving stdout/stderr to logfile. debug mode on Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:19:16 2010 @@ -4,7 +4,7 @@ # LOGFILE="autobuild.log" -( +#( echo "Start a new build at `date -R`" # svn co - trunk/ @@ -30,4 +30,4 @@ # upload echo "Finish the new build at `date -R`" -) >>$LOGFILE +#) >>$LOGFILE From getxsick at codespeak.net Sun Mar 28 16:22:49 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:22:49 +0200 (CEST) Subject: [pypy-svn] r73022 - pypy/build/ubuntu/trunk Message-ID: <20100328142249.4672E282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 16:22:47 2010 New Revision: 73022 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: add extra information for logfile Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:22:47 2010 @@ -5,29 +5,29 @@ LOGFILE="autobuild.log" #( -echo "Start a new build at `date -R`" +echo "--- Start a new build at `date -R`" -# svn co - trunk/ +echo " -- Check out pypy trunk" svn co http://codespeak.net/svn/pypy/trunk pypy-svn REVISION=`svnversion pypy-svn/` find pypy-svn/ -depth -type d -name ".svn" -delete mv pypy-svn pypy-svn$REVISION -# create orig +echo " -- Create orig.tar.gz" tar cfz pypy_svn$REVISION.orig.tar.gz pypy-svn$REVISION/ -# svn co - debian/ +echo " -- Check out debian/ directory" svn co http://codespeak.net/svn/pypy/build/ubuntu/trunk/debian find debian/ -depth -type d -name ".svn" -delete mv debian/ pypy-svn$REVISION -# update changelog +echo " -- Update debian/changelog" dch --newversion svn$REVISION-1 Auto build from trunk -# build a package +echo " -- Build a package" debuild -S -sa # upload -echo "Finish the new build at `date -R`" +echo "--- Finish the new build at `date -R`" #) >>$LOGFILE From getxsick at codespeak.net Sun Mar 28 16:24:50 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:24:50 +0200 (CEST) Subject: [pypy-svn] r73023 - pypy/build/ubuntu/trunk Message-ID: <20100328142450.94D4C282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 16:24:49 2010 New Revision: 73023 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: force removing not empty directories Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:24:49 2010 @@ -10,7 +10,7 @@ echo " -- Check out pypy trunk" svn co http://codespeak.net/svn/pypy/trunk pypy-svn REVISION=`svnversion pypy-svn/` -find pypy-svn/ -depth -type d -name ".svn" -delete +find pypy-svn/ -depth -type d -name ".svn" | xargs rm -rf mv pypy-svn pypy-svn$REVISION echo " -- Create orig.tar.gz" From getxsick at codespeak.net Sun Mar 28 16:26:03 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:26:03 +0200 (CEST) Subject: [pypy-svn] r73024 - pypy/build/ubuntu/trunk Message-ID: <20100328142603.5E063282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 16:26:01 2010 New Revision: 73024 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: same as the last commit Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:26:01 2010 @@ -18,7 +18,7 @@ echo " -- Check out debian/ directory" svn co http://codespeak.net/svn/pypy/build/ubuntu/trunk/debian -find debian/ -depth -type d -name ".svn" -delete +find debian/ -depth -type d -name ".svn" | xargs rm -rf mv debian/ pypy-svn$REVISION echo " -- Update debian/changelog" From getxsick at codespeak.net Sun Mar 28 16:31:54 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 16:31:54 +0200 (CEST) Subject: [pypy-svn] r73025 - pypy/build/ubuntu/trunk Message-ID: <20100328143154.60D01282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 16:31:52 2010 New Revision: 73025 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: redirect stderr to logfile Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 16:31:52 2010 @@ -30,4 +30,4 @@ # upload echo "--- Finish the new build at `date -R`" -#) >>$LOGFILE +#) &>>$LOGFILE From getxsick at codespeak.net Sun Mar 28 17:08:02 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 17:08:02 +0200 (CEST) Subject: [pypy-svn] r73026 - pypy/trunk/pypy/tool Message-ID: <20100328150802.F1A24282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 17:08:00 2010 New Revision: 73026 Modified: pypy/trunk/pypy/tool/runsubprocess.py Log: rollback r72975; deprecated version is better currently Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Sun Mar 28 17:08:00 2010 @@ -44,9 +44,8 @@ # do this at import-time, when the process is still tiny _source = os.path.dirname(os.path.abspath(__file__)) _source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc' - args = ["'%s' '%s'" % (sys.executable, _source)] - pipe = Popen(args, stdout=PIPE, stdin=PIPE, shell=True, close_fds=True) - (_child_stdin, _child_stdout) = (pipe.stdin, pipe.stdout) + _child_stdin, _child_stdout = os.popen2( + "'%s' '%s'" % (sys.executable, _source)) def _run(*args): _child_stdin.write('%r\n' % (args,)) From getxsick at codespeak.net Sun Mar 28 17:09:50 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 17:09:50 +0200 (CEST) Subject: [pypy-svn] r73027 - pypy/build/ubuntu/trunk Message-ID: <20100328150950.B4515282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 17:09:49 2010 New Revision: 73027 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: change current directory if needed Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 17:09:49 2010 @@ -21,12 +21,14 @@ find debian/ -depth -type d -name ".svn" | xargs rm -rf mv debian/ pypy-svn$REVISION +cd pypy-svn$REVISION echo " -- Update debian/changelog" dch --newversion svn$REVISION-1 Auto build from trunk echo " -- Build a package" debuild -S -sa +cd .. # upload echo "--- Finish the new build at `date -R`" From xoraxax at codespeak.net Sun Mar 28 17:20:55 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 17:20:55 +0200 (CEST) Subject: [pypy-svn] r73028 - in pypy/branch/cpython-extension/pypy/annotation: . test Message-ID: <20100328152055.CE6DD282B9D@codespeak.net> Author: xoraxax Date: Sun Mar 28 17:20:54 2010 New Revision: 73028 Modified: pypy/branch/cpython-extension/pypy/annotation/annrpython.py pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py Log: Update build_types to use better code that can also handle varargs. Modified: pypy/branch/cpython-extension/pypy/annotation/annrpython.py ============================================================================== --- pypy/branch/cpython-extension/pypy/annotation/annrpython.py (original) +++ pypy/branch/cpython-extension/pypy/annotation/annrpython.py Sun Mar 28 17:20:54 2010 @@ -86,12 +86,12 @@ """Recursively build annotations about the specific entry point.""" assert isinstance(function, FunctionType), "fix that!" + from pypy.annotation.policy import AnnotatorPolicy + policy = AnnotatorPolicy() # make input arguments and set their type - inputcells = [self.typeannotation(t) for t in input_arg_types] + args_s = [self.typeannotation(t) for t in input_arg_types] - desc = self.bookkeeper.getdesc(function) - desc.getcallfamily() # record this implicit call (hint for back-ends) - flowgraph = desc.specialize(inputcells) + flowgraph, inputcells = self.get_call_parameters(function, args_s, policy) if not isinstance(flowgraph, FunctionGraph): assert isinstance(flowgraph, annmodel.SomeObject) return flowgraph Modified: pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py Sun Mar 28 17:20:54 2010 @@ -3164,6 +3164,13 @@ assert isinstance(s, annmodel.SomeList) assert s.listdef.listitem.resized + def test_varargs(self): + def f(*args): + return args[0] + 42 + a = self.RPythonAnnotator() + s = a.build_types(f, [int, int]) + assert isinstance(s, annmodel.SomeInteger) + def test_listitem_no_mutating(self): from pypy.rlib.debug import check_annotation called = [] From arigo at codespeak.net Sun Mar 28 17:27:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 17:27:54 +0200 (CEST) Subject: [pypy-svn] r73029 - pypy/pysqlite2 Message-ID: <20100328152754.943F3282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 17:27:52 2010 New Revision: 73029 Modified: pypy/pysqlite2/dbapi2.py Log: * Never return None from _get_exception(), because that cannot be raised. Instead, raise ValueError directly if we get SQLITE_OK. * Pass the exception return code to _get_exception() in all cases. Modified: pypy/pysqlite2/dbapi2.py ============================================================================== --- pypy/pysqlite2/dbapi2.py (original) +++ pypy/pysqlite2/dbapi2.py Sun Mar 28 17:27:52 2010 @@ -284,7 +284,7 @@ error_message = sqlite.sqlite3_errmsg(self.db) if error_code == SQLITE_OK: - return None + raise ValueError("error signalled but got SQLITE_OK") elif error_code in (SQLITE_INTERNAL, SQLITE_NOTFOUND): exc = InternalError elif error_code == SQLITE_NOMEM: @@ -371,10 +371,10 @@ next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: - raise self._get_exception() + raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: - raise self._get_exception() + raise self._get_exception(ret) finally: sqlite.sqlite3_finalize(statement) @@ -389,10 +389,10 @@ next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: - raise self._get_exception() + raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: - raise self._get_exception() + raise self._get_exception(ret) finally: sqlite.sqlite3_finalize(statement) @@ -407,10 +407,10 @@ next_char = c_char_p() ret = sqlite.sqlite3_prepare_v2(self.db, sql, -1, byref(statement), next_char) if ret != SQLITE_OK: - raise self._get_exception() + raise self._get_exception(ret) ret = sqlite.sqlite3_step(statement) if ret != SQLITE_DONE: - raise self._get_exception() + raise self._get_exception(ret) finally: sqlite.sqlite3_finalize(statement) @@ -443,7 +443,7 @@ self.closed = True ret = sqlite.sqlite3_close(self.db) if ret != SQLITE_OK: - raise self._get_exception() + raise self._get_exception(ret) def create_collation(self, name, callback): raise NotImplementedError @@ -469,7 +469,7 @@ cast(None, STEP), cast(None, FINAL)) if ret != SQLITE_OK: - raise self._get_exception() + raise self._get_exception(ret) def create_aggregate(self, name, num_args, cls): raise NotImplementedError @@ -529,7 +529,7 @@ self.statement.set_params(params) ret = sqlite.sqlite3_step(self.statement.statement) if ret != SQLITE_DONE: - raise self.connection._get_exception() + raise self.connection._get_exception(ret) self.rowcount += sqlite.sqlite3_changes(self.connection.db) return self @@ -548,13 +548,13 @@ raise ProgrammingError, "Incomplete statement '%s'" % next_char.value ret = sqlite.sqlite3_prepare_v2(self.connection.db, next_char, -1, byref(statement), byref(next_char)) if ret != SQLITE_OK: - raise self.connection._get_exception() + raise self.connection._get_exception(ret) if statement.value is None: break ret = sqlite.sqlite3_step(statement) sqlite.sqlite3_finalize(statement) if ret not in (SQLITE_OK, SQLITE_DONE, SQLITE_ROW): - raise self.connection._get_exception() + raise self.connection._get_exception(ret) if next_char.value is None: break @@ -637,7 +637,7 @@ self.kind = "DQL" if ret != SQLITE_OK: - raise self.con._get_exception() + raise self.con._get_exception(ret) self.con._remember_statement(self) if _check_remaining_sql(next_char.value): raise Warning, "One and only one statement required" @@ -701,7 +701,7 @@ def set_params(self, params): ret = sqlite.sqlite3_reset(self.statement) if ret != SQLITE_OK: - raise self.con._get_exception() + raise self.con._get_exception(ret) if params is None: if sqlite.sqlite3_bind_parameter_count(self.statement) != 0: @@ -754,7 +754,7 @@ return elif ret == SQLITE_ERROR: sqlite.sqlite3_reset(self.statement) - exc = self.con._get_exception() + exc = self.con._get_exception(ret) raise exc else: assert ret == SQLITE_ROW From arigo at codespeak.net Sun Mar 28 17:28:47 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 17:28:47 +0200 (CEST) Subject: [pypy-svn] r73030 - pypy/pysqlite2 Message-ID: <20100328152847.9D03F282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 17:28:46 2010 New Revision: 73030 Modified: pypy/pysqlite2/dbapi2.py Log: Try to import from "libsqlite3.so.0" too. (?) Modified: pypy/pysqlite2/dbapi2.py ============================================================================== --- pypy/pysqlite2/dbapi2.py (original) +++ pypy/pysqlite2/dbapi2.py Sun Mar 28 17:28:46 2010 @@ -33,7 +33,7 @@ paramstyle = "qmark" threadsafety = 1 -names = "sqlite3.dll libsqlite3.so libsqlite3.dylib".split() +names = "sqlite3.dll libsqlite3.so libsqlite3.dylib libsqlite3.so.0".split() for name in names: try: sqlite = cdll.LoadLibrary(name) From arigo at codespeak.net Sun Mar 28 17:31:06 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 17:31:06 +0200 (CEST) Subject: [pypy-svn] r73031 - pypy/pysqlite2 Message-ID: <20100328153106.9B112282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 17:31:05 2010 New Revision: 73031 Modified: pypy/pysqlite2/dbapi2.py Log: Revert r73030. I agree with fijal, it makes little sense. Probably a bug of the system where I am. Modified: pypy/pysqlite2/dbapi2.py ============================================================================== --- pypy/pysqlite2/dbapi2.py (original) +++ pypy/pysqlite2/dbapi2.py Sun Mar 28 17:31:05 2010 @@ -33,7 +33,7 @@ paramstyle = "qmark" threadsafety = 1 -names = "sqlite3.dll libsqlite3.so libsqlite3.dylib libsqlite3.so.0".split() +names = "sqlite3.dll libsqlite3.so libsqlite3.dylib".split() for name in names: try: sqlite = cdll.LoadLibrary(name) From xoraxax at codespeak.net Sun Mar 28 17:35:35 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 17:35:35 +0200 (CEST) Subject: [pypy-svn] r73032 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100328153535.127A2282B9D@codespeak.net> Author: xoraxax Date: Sun Mar 28 17:35:33 2010 New Revision: 73032 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: RPythonify code. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 17:35:33 2010 @@ -19,6 +19,7 @@ from pypy.interpreter.gateway import ObjSpace, unwrap_spec from pypy.objspace.std.stringobject import W_StringObject from pypy.rlib.entrypoint import entrypoint +from pypy.rlib.unroll import unrolling_iterable # CPython 2.4 compatibility from py.builtin import BaseException @@ -93,6 +94,9 @@ self.argnames = argnames[1:] assert len(self.argnames) == len(self.argtypes) + def _freeze_(self): + return True + def get_llhelper(self, space): llh = getattr(self, '_llhelper', None) if llh is None: @@ -119,25 +123,33 @@ def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed, error) func.api_func = api_function + # the function is always wrapped so lets inline it into the wrapper + func._always_inline_ = True if error is _NOT_SPECIFIED: raise ValueError("function %s has no return value for exceptions" % func) def make_unwrapper(catch_exception): + names = api_function.argnames + types_names_enum_ui = unrolling_iterable(enumerate(zip(api_function.argtypes, + names, [name.startswith("w_") for name in names]))) def unwrapper(space, *args): - "NOT_RPYTHON: XXX unsure" - newargs = [] - to_decref = [] - for i, arg in enumerate(args): - if api_function.argtypes[i] is PyObject: - if (isinstance(arg, W_Root) and - not api_function.argnames[i].startswith('w_')): - arg = make_ref(space, arg) - to_decref.append(arg) - elif (not isinstance(arg, W_Root) and - api_function.argnames[i].startswith('w_')): - arg = from_ref(space, arg) - newargs.append(arg) + newargs = () + to_decref = () + for i, (typ, name, is_wrapped) in types_names_enum_ui: + if typ is PyObject: + if (isinstance(args[i], W_Root) and + not is_wrapped): + arg = make_ref(space, args[i]) + to_decref += (arg, ) + elif (not isinstance(args[i], W_Root) and + is_wrapped): + arg = from_ref(space, args[i]) + else: + arg = args[i] + else: + arg = args[i] + newargs += (arg, ) try: try: return func(space, *newargs) @@ -238,22 +250,26 @@ return lltype.Struct(hints["c_name"], hints=hints, *new_fields) def debug_refcount(*args, **kwargs): - frame_stackdepth = kwargs.pop("frame_stackdepth", 2) - assert not kwargs if DEBUG_REFCOUNT: + frame_stackdepth = kwargs.pop("frame_stackdepth", 2) + assert not kwargs frame = sys._getframe(frame_stackdepth) - print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), + print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), for arg in args: print >>sys.stderr, arg, print >>sys.stderr +if not DEBUG_REFCOUNT: + def debug_refcount(arg0, arg1, arg2, arg3=None, arg4=None, frame_stackdepth=None): + pass + def make_ref(space, w_obj, borrowed=False, steal=False): from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF if w_obj is None: return lltype.nullptr(PyObject.TO) assert isinstance(w_obj, W_Root) state = space.fromcache(State) - py_obj = state.py_objects_w2r.get(w_obj) + py_obj = state.py_objects_w2r.get(w_obj, None) if py_obj is None: from pypy.module.cpyext.typeobject import allocate_type_obj,\ W_PyCTypeObject, W_PyCObject @@ -269,11 +285,11 @@ # Py_INCREF(space, pto) basicsize = pto._obj.c_tp_basicsize T = get_padded_type(PyObject.TO, basicsize) - py_obj = lltype.malloc(T, None, flavor="raw", zero=True) + py_obj = lltype.malloc(T, flavor="raw", zero=True) py_obj.c_ob_refcnt = 1 py_obj.c_ob_type = rffi.cast(PyObject, pto) elif isinstance(w_obj, W_StringObject): - py_obj = lltype.malloc(PyStringObject.TO, None, flavor='raw', zero=True) + py_obj = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True) py_obj.c_size = len(space.str_w(w_obj)) py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) @@ -281,7 +297,7 @@ py_obj.c_ob_refcnt = 1 py_obj.c_ob_type = rffi.cast(PyObject, pto) else: - py_obj = lltype.malloc(PyObject.TO, None, flavor="raw", zero=True) + py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True) py_obj.c_ob_refcnt = 1 pto = make_ref(space, space.type(w_obj)) py_obj.c_ob_type = rffi.cast(PyObject, pto) @@ -348,7 +364,7 @@ raise NullPointerException if container_ptr == -1: return - borrowees = state.borrow_mapping.get(container_ptr) + borrowees = state.borrow_mapping.get(container_ptr, None) if borrowees is None: state.borrow_mapping[container_ptr] = borrowees = {} obj_ptr = rffi.cast(ADDR, obj) @@ -365,20 +381,25 @@ # Make the wrapper for the cases (1) and (2) def make_wrapper(space, callable): + names = callable.api_func.argnames + argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes, + names, [name.startswith("w_") for name in names]))) def wrapper(*args): - boxed_args = [] + boxed_args = () # XXX use unrolling_iterable here if DEBUG_WRAPPER: print >>sys.stderr, callable, - for i, typ in enumerate(callable.api_func.argtypes): + for i, (typ, argname, is_wrapped) in argtypes_enum_ui: arg = args[i] if (typ is PyObject and - callable.api_func.argnames[i].startswith('w_')): + is_wrapped): if arg: - arg = from_ref(space, arg) + arg_conv = from_ref(space, arg) else: - arg = None - boxed_args.append(arg) + arg_conv = None + else: + arg_conv = arg + boxed_args += (arg_conv, ) state = space.fromcache(State) try: retval = callable(space, *boxed_args) @@ -391,8 +412,9 @@ except BaseException, e: failed = True state.set_exception(space.w_SystemError, space.wrap(str(e))) - import traceback - traceback.print_exc() + if not we_are_translated(): + import traceback + traceback.print_exc() else: failed = False @@ -557,7 +579,7 @@ def setup_library(space): for name, func in FUNCTIONS.iteritems(): - deco = entrypoint("cpyext", (tuple(func.argtypes), ), name) + deco = entrypoint("cpyext", func.argtypes, name) deco(func.get_wrapper(space)) @unwrap_spec(ObjSpace, str, str) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sun Mar 28 17:35:33 2010 @@ -21,7 +21,8 @@ # without modifying the r2w/w2r dicts _Py_Dealloc(space, obj) else: - w_obj = state.py_objects_r2w.pop(ptr) + w_obj = state.py_objects_r2w[ptr] + del state.py_objects_r2w[ptr] _Py_Dealloc(space, obj) del state.py_objects_w2r[w_obj] if ptr in state.borrow_mapping: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Sun Mar 28 17:35:33 2010 @@ -11,7 +11,7 @@ self.reset() def reset(self): - self.py_objects_w2r = identity_dict() # { w_obj -> raw PyObject } + self.py_objects_w2r = {} # { w_obj -> raw PyObject } self.py_objects_r2w = {} # { addr of raw PyObject -> w_obj } self.borrow_mapping = {} # { addr of container -> { addr of containee -> None } } self.borrowed_objects = {} # { addr of containee -> None } Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Sun Mar 28 17:35:33 2010 @@ -20,7 +20,7 @@ ptr = make_ref(space, space.wrap(s)) return rffi.cast(PyStringObject, ptr) else: - py_str = lltype.malloc(PyStringObject.TO, None, flavor='raw') + py_str = lltype.malloc(PyStringObject.TO, flavor='raw') py_str.c_ob_refcnt = 1 buflen = length + 1 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Sun Mar 28 17:35:33 2010 @@ -161,7 +161,7 @@ assert not isinstance(w_type, W_PyCTypeObject) assert isinstance(w_type, W_TypeObject) - pto = lltype.malloc(PyTypeObject, None, flavor="raw", zero=True) + pto = lltype.malloc(PyTypeObject, flavor="raw", zero=True) pto.c_ob_refcnt = 1 # put the type object early into the dict # to support dependency cycles like object/type From arigo at codespeak.net Sun Mar 28 17:42:11 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 17:42:11 +0200 (CEST) Subject: [pypy-svn] r73033 - pypy/pysqlite2/test Message-ID: <20100328154211.96186282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 17:42:10 2010 New Revision: 73033 Modified: pypy/pysqlite2/test/userfunctions.py Log: Asking for -100 arguments gives a SQLITE_MISUSE in at least one version of libsqlite3.so. It makes sense I suppose. Fix test. Modified: pypy/pysqlite2/test/userfunctions.py ============================================================================== --- pypy/pysqlite2/test/userfunctions.py (original) +++ pypy/pysqlite2/test/userfunctions.py Sun Mar 28 17:42:10 2010 @@ -140,8 +140,9 @@ def CheckFuncErrorOnCreate(self): try: self.con.create_function("bla", -100, lambda x: 2*x) - self.fail("should have raised an OperationalError") - except sqlite.OperationalError: + self.fail("should have raised an OperationalError " + "or ProgrammingError") + except (sqlite.OperationalError, sqlite.ProgrammingError): pass def CheckFuncRefCount(self): From arigo at codespeak.net Sun Mar 28 17:45:31 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 17:45:31 +0200 (CEST) Subject: [pypy-svn] r73034 - pypy/pysqlite2 Message-ID: <20100328154531.909C8282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 17:45:30 2010 New Revision: 73034 Modified: pypy/pysqlite2/dbapi2.py Log: Redo r73031 (sorry) after idnar convinced me that opening libsqlite3.so.0 is the "right" thing to do. Modified: pypy/pysqlite2/dbapi2.py ============================================================================== --- pypy/pysqlite2/dbapi2.py (original) +++ pypy/pysqlite2/dbapi2.py Sun Mar 28 17:45:30 2010 @@ -33,7 +33,7 @@ paramstyle = "qmark" threadsafety = 1 -names = "sqlite3.dll libsqlite3.so libsqlite3.dylib".split() +names = "sqlite3.dll libsqlite3.so.0 libsqlite3.so libsqlite3.dylib".split() for name in names: try: sqlite = cdll.LoadLibrary(name) From xoraxax at codespeak.net Sun Mar 28 17:50:59 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 17:50:59 +0200 (CEST) Subject: [pypy-svn] r73035 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100328155059.EC84A282B9D@codespeak.net> Author: xoraxax Date: Sun Mar 28 17:50:58 2010 New Revision: 73035 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: Further rpythonify code. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 17:50:58 2010 @@ -604,47 +604,54 @@ initfunc.call(lltype.Void) state.check_and_raise_exception() -def generic_cpy_call(space, func, *args, **kwargs): - from pypy.module.cpyext.macros import Py_DECREF - from pypy.module.cpyext.pyerrors import PyErr_Occurred - - decref_args = kwargs.pop("decref_args", True) - assert not kwargs - boxed_args = [] - for arg in args: # XXX UI needed - if isinstance(arg, W_Root) or arg is None: - boxed_args.append(make_ref(space, arg)) - else: - boxed_args.append(arg) - result = func(*boxed_args) - try: - FT = lltype.typeOf(func).TO - if FT.RESULT is PyObject: - ret = from_ref(space, result) - if result: - # The object reference returned from a C function - # that is called from Python must be an owned reference - # - ownership is transferred from the function to its caller. - Py_DECREF(space, result) - - # Check for exception consistency - has_error = PyErr_Occurred(space) is not None - has_result = ret is not None - if has_error and has_result: - raise OperationError(space.w_SystemError, space.wrap( - "An exception was set, but function returned a value")) - elif not has_error and not has_result: - raise OperationError(space.w_SystemError, space.wrap( - "Function returned a NULL result without setting an exception")) - - if has_error: - state = space.fromcache(State) - state.check_and_raise_exception() - - return ret - finally: - if decref_args: - for arg, ref in zip(args, boxed_args): - if isinstance(arg, W_Root) and ref: - Py_DECREF(space, ref) +def make_generic_cpy_call_func(decref_args): + def generic_cpy_call(space, func, *args): + from pypy.module.cpyext.macros import Py_DECREF + from pypy.module.cpyext.pyerrors import PyErr_Occurred + + boxed_args = () + for arg in args: # XXX UI needed + if isinstance(arg, W_Root) or arg is None: + boxed_args += (make_ref(space, arg), ) + else: + boxed_args += (arg, ) + result = func(*boxed_args) + try: + FT = lltype.typeOf(func).TO + if FT.RESULT is PyObject: + ret = from_ref(space, result) + if result: + # The object reference returned from a C function + # that is called from Python must be an owned reference + # - ownership is transferred from the function to its caller. + Py_DECREF(space, result) + + # Check for exception consistency + has_error = PyErr_Occurred(space) is not None + has_result = ret is not None + if has_error and has_result: + raise OperationError(space.w_SystemError, space.wrap( + "An exception was set, but function returned a value")) + elif not has_error and not has_result: + raise OperationError(space.w_SystemError, space.wrap( + "Function returned a NULL result without setting an exception")) + + if has_error: + state = space.fromcache(State) + state.check_and_raise_exception() + + return ret + finally: + if decref_args: + i = 0 + while i < len(args): + arg = args[i] + ref = boxed_args[i] + if isinstance(arg, W_Root) and ref: + Py_DECREF(space, ref) + i += 1 + return generic_cpy_call + +generic_cpy_call = make_generic_cpy_call_func(True) +generic_cpy_call_dont_decref = make_generic_cpy_call_func(False) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Sun Mar 28 17:50:58 2010 @@ -62,10 +62,10 @@ def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr - from pypy.module.cpyext.methodobject import generic_cpy_call + from pypy.module.cpyext.api import generic_cpy_call_dont_decref pto = obj.c_ob_type pto = rffi.cast(PyTypeObjectPtr, pto) #print >>sys.stderr, "Calling dealloc slot of", obj, \ # "'s type which is", rffi.charp2str(pto.c_tp_name) - generic_cpy_call(space, pto.c_tp_dealloc, obj, decref_args=False) + generic_cpy_call_dont_decref(space, pto.c_tp_dealloc, obj) From xoraxax at codespeak.net Sun Mar 28 18:05:07 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 18:05:07 +0200 (CEST) Subject: [pypy-svn] r73036 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100328160507.593DE282B9D@codespeak.net> Author: xoraxax Date: Sun Mar 28 18:05:05 2010 New Revision: 73036 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Add specialization. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 18:05:05 2010 @@ -20,6 +20,7 @@ from pypy.objspace.std.stringobject import W_StringObject from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib.objectmodel import specialize # CPython 2.4 compatibility from py.builtin import BaseException @@ -605,6 +606,7 @@ state.check_and_raise_exception() def make_generic_cpy_call_func(decref_args): + @specialize.argtype(2) def generic_cpy_call(space, func, *args): from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_Occurred From arigo at codespeak.net Sun Mar 28 18:08:43 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Mar 2010 18:08:43 +0200 (CEST) Subject: [pypy-svn] r73037 - pypy/branch/asmgcc-64/pypy/translator/c/gcc Message-ID: <20100328160843.DFA18282B9D@codespeak.net> Author: arigo Date: Sun Mar 28 18:08:42 2010 New Revision: 73037 Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Log: In-progress. Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/instruction.py Sun Mar 28 18:08:42 2010 @@ -93,7 +93,11 @@ class InsnFunctionStart(Insn): framesize = 0 previous_insns = () - def __init__(self, registers): + REGS_ARGS_ON_64BIT = dict.fromkeys(['%rdi', '%rsi', '%rdx', + '%rcx', '%r8', '%r9']) + + def __init__(self, registers, WORD): + self.WORD = WORD self.arguments = {} for reg in registers: self.arguments[reg] = somenewvalue @@ -107,6 +111,8 @@ # the function's calling convention was optimized by gcc: # the 3 registers above are then used to pass arguments pass + elif self.WORD == 8 and localvar in self.REGS_ARGS_ON_64BIT: + pass else: assert (isinstance(localvar, LocalVarAbstract) and localvar.ofs_from_frame_end > 0), ( Modified: pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py ============================================================================== --- pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py (original) +++ pypy/branch/asmgcc-64/pypy/translator/c/gcc/trackgcroot.py Sun Mar 28 18:08:42 2010 @@ -37,6 +37,19 @@ cls.r_jmp_source = re.compile(r"\d*[(](%[\w]+)[,)]") def __init__(self, funcname, lines, filetag=0): + # make sure that we don't create an instance of a class and later an + # instance of a subclass, as we might do in some tests. This would + # seriously mess up find_missing_visit_method. + if '_abstractclass' not in self.__class__.__dict__: + for bc in self.__class__.__mro__: + if bc is not object: + assert getattr(bc, '_abstractclass', True), \ + "already instantiated the parent class!" + bc._abstractclass = True + self.__class__._abstractclass = False + assert self.__class__.__dict__['_abstractclass'] == False, \ + "already instantiated a subclass!" + # self.funcname = funcname self.lines = lines self.uses_frame_pointer = False @@ -151,7 +164,7 @@ lst.append(previnsn) def parse_instructions(self): - self.insns = [InsnFunctionStart(self.CALLEE_SAVE_REGISTERS)] + self.insns = [InsnFunctionStart(self.CALLEE_SAVE_REGISTERS, self.WORD)] ignore_insns = False for lineno, line in enumerate(self.lines): if lineno < self.skip: @@ -191,28 +204,31 @@ del self.currentlineno - def find_missing_visit_method(self, opname): + @classmethod + def find_missing_visit_method(cls, opname): + # Add the correct visit_ method to the class. + # # if opname ends with an 'l' (on 32-bit) or a 'q' (on 64-bit), # try to find the method that ends with an 'X'. On Windows, # where SUFFIX='', try to just append 'X'. - if opname.endswith(self.SUFFIX): - basename = opname[:len(opname)-len(self.SUFFIX)] + if opname.endswith(cls.SUFFIX): + basename = opname[:len(opname)-len(cls.SUFFIX)] try: - method = getattr(self, 'visit_' + basename + 'X') + method = getattr(cls, 'visit_' + basename + 'X') except AttributeError: pass # not found else: - setattr(self, 'visit_' + opname, method) + setattr(cls, 'visit_' + opname, method) return # not found. This is the case only for operations that are # no-ops as far as we are concerned, but check if it is really # in IGNORE_OPS_WITH_PREFIXES. prefix = opname - while prefix not in self.IGNORE_OPS_WITH_PREFIXES: + while prefix not in cls.IGNORE_OPS_WITH_PREFIXES: prefix = prefix[:-1] if not prefix: raise UnrecognizedOperation(opname) - setattr(self, 'visit_' + opname, self.visit_nop) + setattr(cls, 'visit_' + opname, cls.visit_nop) def list_collecting_call_insns(self): return [insn for insn in self.insns if isinstance(insn, InsnCall) @@ -400,13 +416,15 @@ # arithmetic operations should not produce GC pointers 'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc', 'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv', - 'bswap', 'bt', 'rdtsc', + 'bswap', 'bt', 'rdtsc', 'punpck', 'pshuf', # zero-extending moves should not produce GC pointers - 'movz', + 'movz', 'cltq', # quadword operations: ignored on 32-bit 'movq', # conversely, ignore 32-bit operations on 64-bit 'xorl', 'movl', 'addl', 'subl', 'andl', 'orl', 'leal', + # the following should only be used to load constant integers + 'movabsq', ]) visit_movb = visit_nop @@ -838,6 +856,9 @@ ElfFunctionGcRootTracker.init_regexp() +class Elf32FunctionGcRootTracker(ElfFunctionGcRootTracker): + pass + class Elf64FunctionGcRootTracker(ElfFunctionGcRootTracker): WORD = 8 SUFFIX = 'q' @@ -1093,7 +1114,7 @@ class ElfAssemblerParser(AssemblerParser): format = "elf" - FunctionGcRootTracker = ElfFunctionGcRootTracker + FunctionGcRootTracker = Elf32FunctionGcRootTracker @classmethod def find_functions(cls, iterlines): From getxsick at codespeak.net Sun Mar 28 18:38:10 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 18:38:10 +0200 (CEST) Subject: [pypy-svn] r73038 - in pypy/build/ubuntu: 1.2.0/debian trunk/debian Message-ID: <20100328163810.C4C5A282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 18:38:09 2010 New Revision: 73038 Modified: pypy/build/ubuntu/1.2.0/debian/control pypy/build/ubuntu/trunk/debian/control Log: update Standards-Version to 3.8.3 IMHO it's a bit stupid but Debian policy.. Modified: pypy/build/ubuntu/1.2.0/debian/control ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/control (original) +++ pypy/build/ubuntu/1.2.0/debian/control Sun Mar 28 18:38:09 2010 @@ -3,7 +3,7 @@ Priority: extra Maintainer: Bartosz Skowron Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 -Standards-Version: 3.8.0 +Standards-Version: 3.8.3 Homepage: http://pypy.org Package: pypy-dev Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sun Mar 28 18:38:09 2010 @@ -3,7 +3,7 @@ Priority: extra Maintainer: Bartosz Skowron Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 -Standards-Version: 3.8.0 +Standards-Version: 3.8.3 Homepage: http://pypy.org Package: pypy-dev From getxsick at codespeak.net Sun Mar 28 18:49:50 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 18:49:50 +0200 (CEST) Subject: [pypy-svn] r73039 - pypy/build/ubuntu/trunk/debian Message-ID: <20100328164950.762B3282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 18:49:49 2010 New Revision: 73039 Modified: pypy/build/ubuntu/trunk/debian/control Log: since r73034, there is no need to require -dev package Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sun Mar 28 18:49:49 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.6 Standards-Version: 3.8.3 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.6 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-0, libdb4.6 Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. From getxsick at codespeak.net Sun Mar 28 18:54:46 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 18:54:46 +0200 (CEST) Subject: [pypy-svn] r73040 - pypy/build/ubuntu/trunk Message-ID: <20100328165446.CC863282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 18:54:45 2010 New Revision: 73040 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: add upcoming release tag to upstream version Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 18:54:45 2010 @@ -4,6 +4,7 @@ # LOGFILE="autobuild.log" +NEXT_RELEASE=1.3 #( echo "--- Start a new build at `date -R`" @@ -11,19 +12,19 @@ svn co http://codespeak.net/svn/pypy/trunk pypy-svn REVISION=`svnversion pypy-svn/` find pypy-svn/ -depth -type d -name ".svn" | xargs rm -rf -mv pypy-svn pypy-svn$REVISION +mv pypy-svn pypy-$NEXT_RELEASE~svn$REVISION echo " -- Create orig.tar.gz" -tar cfz pypy_svn$REVISION.orig.tar.gz pypy-svn$REVISION/ +tar cfz pypy_$NEXT_RELEASE~svn$REVISION.orig.tar.gz pypy-$NEXT_RELEASE~svn$REVISION/ echo " -- Check out debian/ directory" svn co http://codespeak.net/svn/pypy/build/ubuntu/trunk/debian find debian/ -depth -type d -name ".svn" | xargs rm -rf -mv debian/ pypy-svn$REVISION +mv debian/ pypy-$NEXT_RELEASE~svn$REVISION -cd pypy-svn$REVISION +cd pypy-$NEXT_RELEASE~svn$REVISION echo " -- Update debian/changelog" -dch --newversion svn$REVISION-1 Auto build from trunk +dch --newversion $NEXT_RELEASE~svn$REVISION-1 Auto build from trunk echo " -- Build a package" debuild -S -sa From getxsick at codespeak.net Sun Mar 28 19:03:03 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 19:03:03 +0200 (CEST) Subject: [pypy-svn] r73041 - pypy/build/ubuntu/trunk/debian Message-ID: <20100328170303.CD340282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 19:03:02 2010 New Revision: 73041 Modified: pypy/build/ubuntu/trunk/debian/control Log: remove python-dev from build-depends, it's not needed anymore. thanks to santagada for notice it Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sun Mar 28 19:03:02 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.6 +Build-Depends: debhelper (>= 7), libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.6 Standards-Version: 3.8.3 Homepage: http://pypy.org From getxsick at codespeak.net Sun Mar 28 19:12:07 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 19:12:07 +0200 (CEST) Subject: [pypy-svn] r73042 - in pypy/build/ubuntu: 1.2.0/debian trunk/debian Message-ID: <20100328171207.0E4B5282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 19:12:05 2010 New Revision: 73042 Modified: pypy/build/ubuntu/1.2.0/debian/control pypy/build/ubuntu/trunk/debian/control Log: switch required libdb to 4.5 Modified: pypy/build/ubuntu/1.2.0/debian/control ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/control (original) +++ pypy/build/ubuntu/1.2.0/debian/control Sun Mar 28 19:12:05 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.6 +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.5 Standards-Version: 3.8.3 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.6 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.5 Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sun Mar 28 19:12:05 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.6 +Build-Depends: debhelper (>= 7), libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.5 Standards-Version: 3.8.3 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-0, libdb4.6 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-0, libdb4.5 Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. From benjamin at codespeak.net Sun Mar 28 20:41:14 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Sun, 28 Mar 2010 20:41:14 +0200 (CEST) Subject: [pypy-svn] r73043 - pypy/trunk/pypy/objspace/flow Message-ID: <20100328184114.1B2B2282B9D@codespeak.net> Author: benjamin Date: Sun Mar 28 20:41:12 2010 New Revision: 73043 Modified: pypy/trunk/pypy/objspace/flow/model.py Log: kill reallyalloperations() Modified: pypy/trunk/pypy/objspace/flow/model.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/model.py (original) +++ pypy/trunk/pypy/objspace/flow/model.py Sun Mar 28 20:41:12 2010 @@ -206,16 +206,10 @@ txt = "%s(%s)" % (txt, self.exitswitch) return txt - def reallyalloperations(self): - """Iterate over all operations, including cleanup sub-operations. - XXX remove!""" - for op in self.operations: - yield op - def getvariables(self): "Return all variables mentioned in this Block." result = self.inputargs[:] - for op in self.reallyalloperations(): + for op in self.operations: result += op.args result.append(op.result) return uniqueitems([w for w in result if isinstance(w, Variable)]) @@ -223,7 +217,7 @@ def getconstants(self): "Return all constants mentioned in this Block." result = self.inputargs[:] - for op in self.reallyalloperations(): + for op in self.operations: result += op.args return uniqueitems([w for w in result if isinstance(w, Constant)]) @@ -231,7 +225,7 @@ for a in mapping: assert isinstance(a, Variable), a self.inputargs = [mapping.get(a, a) for a in self.inputargs] - for op in self.reallyalloperations(): + for op in self.operations: op.args = [mapping.get(a, a) for a in op.args] op.result = mapping.get(op.result, op.result) self.exitswitch = mapping.get(self.exitswitch, self.exitswitch) From getxsick at codespeak.net Sun Mar 28 21:48:55 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 21:48:55 +0200 (CEST) Subject: [pypy-svn] r73044 - in pypy/build/ubuntu: 1.2.0/debian trunk/debian Message-ID: <20100328194855.84676282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 21:48:50 2010 New Revision: 73044 Modified: pypy/build/ubuntu/1.2.0/debian/control pypy/build/ubuntu/trunk/debian/control Log: use libdb-dev instead of libdb4.5. thanks to amaury Modified: pypy/build/ubuntu/1.2.0/debian/control ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/control (original) +++ pypy/build/ubuntu/1.2.0/debian/control Sun Mar 28 21:48:50 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb4.5 +Build-Depends: debhelper (>= 7), python-dev, libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-dev, libdb-dev Standards-Version: 3.8.3 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb4.5 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-dev, libdb-dev Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. Modified: pypy/build/ubuntu/trunk/debian/control ============================================================================== --- pypy/build/ubuntu/trunk/debian/control (original) +++ pypy/build/ubuntu/trunk/debian/control Sun Mar 28 21:48:50 2010 @@ -2,7 +2,7 @@ Section: python Priority: extra Maintainer: Bartosz Skowron -Build-Depends: debhelper (>= 7), libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb4.5 +Build-Depends: debhelper (>= 7), libgc-dev, libbz2-dev, python-ctypes, libreadline5-dev, procps, zlib1g-dev, libffi-dev, libssl-dev, libexpat1-dev, libsqlite3-0, libdb-dev Standards-Version: 3.8.3 Homepage: http://pypy.org @@ -22,7 +22,7 @@ Package: pypy Architecture: i386 -Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-0, libdb4.5 +Depends: ${shlibs:Depends}, ${misc:Depends}, pypy-lib, zlib1g, libsqlite3-0, libdb-dev Description: python interpreter with Just in time compiler This package provides a binary version of the compiled interpreter with Just in time compilter, together with several supported modules. From xoraxax at codespeak.net Sun Mar 28 22:02:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Mar 2010 22:02:21 +0200 (CEST) Subject: [pypy-svn] r73045 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include Message-ID: <20100328200221.28715282B9D@codespeak.net> Author: xoraxax Date: Sun Mar 28 22:02:19 2010 New Revision: 73045 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c Log: Err on implicit func decls, comment out .c files. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sun Mar 28 22:02:19 2010 @@ -540,6 +540,10 @@ '\n'.join(functions)) # Build code and get pointer to the structure + kwds = {} + if sys.platform != "win32": + kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] + eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_sources=[code], @@ -547,6 +551,7 @@ include_dir / "pyerrors.c", include_dir / "modsupport.c"], export_symbols=['pypyAPI'] + export_symbols, + **kwds ) eci = eci.convert_sources_to_files() modulename = platform.platform.compile( Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c Sun Mar 28 22:02:19 2010 @@ -1,6 +1,7 @@ #include #include - +#if 0 +unsupported functions in it int PyModule_AddObject(PyObject *m, const char *name, PyObject *o) { @@ -29,3 +30,4 @@ Py_DECREF(o); return 0; } +#endif Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c Sun Mar 28 22:02:19 2010 @@ -2,6 +2,8 @@ #include #include #include +#if 0 +depends on unavailable functions PyObject * PyErr_NewException(char *name, PyObject *base, PyObject *dict) @@ -52,3 +54,4 @@ Py_XDECREF(modulename); return result; } +#endif From getxsick at codespeak.net Sun Mar 28 22:30:07 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 22:30:07 +0200 (CEST) Subject: [pypy-svn] r73046 - pypy/build/ubuntu/trunk Message-ID: <20100328203007.5BCDE282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 22:30:05 2010 New Revision: 73046 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: generate packages for set of series Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 22:30:05 2010 @@ -1,6 +1,6 @@ #!/bin/sh # -# Build pypy trunk PPA package and upload it +# Build pypy trunk PPA packages and upload it # LOGFILE="autobuild.log" @@ -22,15 +22,19 @@ find debian/ -depth -type d -name ".svn" | xargs rm -rf mv debian/ pypy-$NEXT_RELEASE~svn$REVISION -cd pypy-$NEXT_RELEASE~svn$REVISION -echo " -- Update debian/changelog" -dch --newversion $NEXT_RELEASE~svn$REVISION-1 Auto build from trunk +for serie in lucid karmic jaunty +do + echo " - Preparing $serie package" + cd pypy-$NEXT_RELEASE~svn$REVISION + echo " -- Update debian/changelog" + dch --newversion $NEXT_RELEASE~svn$REVISION+${serie}f Auto build from trunk -echo " -- Build a package" -debuild -S -sa + echo " -- Build a package" + debuild -S -sa -cd .. -# upload + cd .. + # upload +done echo "--- Finish the new build at `date -R`" #) &>>$LOGFILE From getxsick at codespeak.net Sun Mar 28 22:31:01 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 22:31:01 +0200 (CEST) Subject: [pypy-svn] r73047 - pypy/build/ubuntu/trunk Message-ID: <20100328203101.E6721282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 22:31:00 2010 New Revision: 73047 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: remove created files and dirs before exiting Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 22:31:00 2010 @@ -36,5 +36,6 @@ # upload done +rm -rf pypy* echo "--- Finish the new build at `date -R`" #) &>>$LOGFILE From getxsick at codespeak.net Sun Mar 28 22:37:58 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 22:37:58 +0200 (CEST) Subject: [pypy-svn] r73048 - pypy/build/ubuntu/trunk Message-ID: <20100328203758.5E853282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 22:37:57 2010 New Revision: 73048 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: typo Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 22:37:57 2010 @@ -27,7 +27,7 @@ echo " - Preparing $serie package" cd pypy-$NEXT_RELEASE~svn$REVISION echo " -- Update debian/changelog" - dch --newversion $NEXT_RELEASE~svn$REVISION+${serie}f Auto build from trunk + dch --newversion $NEXT_RELEASE~svn$REVISION+${serie}1 Auto build from trunk echo " -- Build a package" debuild -S -sa From afa at codespeak.net Sun Mar 28 22:47:00 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 28 Mar 2010 22:47:00 +0200 (CEST) Subject: [pypy-svn] r73049 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100328204700.7B3E6282B9D@codespeak.net> Author: afa Date: Sun Mar 28 22:46:59 2010 New Revision: 73049 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Log: Fix tests on Windows, where variable declarations must appear at the start of a block. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py Sun Mar 28 22:46:59 2010 @@ -22,8 +22,7 @@ return NULL; } } - PyObject *ret = PyInt_FromLong(x + 1); - return ret; + return PyInt_FromLong(x + 1); """ ) ]) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Sun Mar 28 22:46:59 2010 @@ -19,10 +19,8 @@ PyObject *l = PyTuple_GetItem(args, 0); int index = PyInt_AsLong(PyTuple_GetItem(args, 1)); Py_INCREF(Py_None); - int res = PyList_SetItem(l, index, Py_None); - if (res == -1) { + if (PyList_SetItem(l, index, Py_None) < 0) return NULL; - } Py_INCREF(Py_None); return Py_None; """ From getxsick at codespeak.net Sun Mar 28 23:17:11 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 23:17:11 +0200 (CEST) Subject: [pypy-svn] r73050 - pypy/build/ubuntu/trunk Message-ID: <20100328211711.11BF1282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 23:17:09 2010 New Revision: 73050 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: add date to version Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 23:17:09 2010 @@ -11,23 +11,24 @@ echo " -- Check out pypy trunk" svn co http://codespeak.net/svn/pypy/trunk pypy-svn REVISION=`svnversion pypy-svn/` +SVNTAG="svn$(date +%Y%m%d)r$REVISION" find pypy-svn/ -depth -type d -name ".svn" | xargs rm -rf -mv pypy-svn pypy-$NEXT_RELEASE~svn$REVISION +mv pypy-svn pypy-$NEXT_RELEASE~$SVNTAG echo " -- Create orig.tar.gz" -tar cfz pypy_$NEXT_RELEASE~svn$REVISION.orig.tar.gz pypy-$NEXT_RELEASE~svn$REVISION/ +tar cfz pypy_$NEXT_RELEASE~$SVNTAG.orig.tar.gz pypy-$NEXT_RELEASE~$SVNTAG/ echo " -- Check out debian/ directory" svn co http://codespeak.net/svn/pypy/build/ubuntu/trunk/debian find debian/ -depth -type d -name ".svn" | xargs rm -rf -mv debian/ pypy-$NEXT_RELEASE~svn$REVISION +mv debian/ pypy-$NEXT_RELEASE~$SVNTAG for serie in lucid karmic jaunty do echo " - Preparing $serie package" - cd pypy-$NEXT_RELEASE~svn$REVISION + cd pypy-$NEXT_RELEASE~$SVNTAG echo " -- Update debian/changelog" - dch --newversion $NEXT_RELEASE~svn$REVISION+${serie}1 Auto build from trunk + dch --newversion $NEXT_RELEASE~$SVNTAG+${serie}1 Auto build from trunk echo " -- Build a package" debuild -S -sa From getxsick at codespeak.net Sun Mar 28 23:22:09 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 23:22:09 +0200 (CEST) Subject: [pypy-svn] r73051 - pypy/build/ubuntu/trunk Message-ID: <20100328212209.513D9282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 23:22:08 2010 New Revision: 73051 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: update changelog only for a specic serie Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 23:22:08 2010 @@ -23,11 +23,13 @@ find debian/ -depth -type d -name ".svn" | xargs rm -rf mv debian/ pypy-$NEXT_RELEASE~$SVNTAG +cp pypy-$NEXT_RELEASE~$SVNTAG/debian/changelog changelog.old for serie in lucid karmic jaunty do echo " - Preparing $serie package" cd pypy-$NEXT_RELEASE~$SVNTAG echo " -- Update debian/changelog" + cp ../changelog.old debian/changelog dch --newversion $NEXT_RELEASE~$SVNTAG+${serie}1 Auto build from trunk echo " -- Build a package" From getxsick at codespeak.net Sun Mar 28 23:23:22 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Sun, 28 Mar 2010 23:23:22 +0200 (CEST) Subject: [pypy-svn] r73052 - pypy/build/ubuntu/trunk Message-ID: <20100328212322.CF0E9282B9D@codespeak.net> Author: getxsick Date: Sun Mar 28 23:23:21 2010 New Revision: 73052 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: remove temporary changelog before exiting Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Sun Mar 28 23:23:21 2010 @@ -39,6 +39,7 @@ # upload done +rm changelog.old rm -rf pypy* echo "--- Finish the new build at `date -R`" #) &>>$LOGFILE From getxsick at codespeak.net Mon Mar 29 00:02:42 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 00:02:42 +0200 (CEST) Subject: [pypy-svn] r73053 - pypy/build/ubuntu/trunk Message-ID: <20100328220242.BDD81282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 00:02:41 2010 New Revision: 73053 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: Use Debian revision. It avoids to create multiple TAR archives. Use orig.tar.gz + diff files instead. Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 00:02:41 2010 @@ -30,7 +30,7 @@ cd pypy-$NEXT_RELEASE~$SVNTAG echo " -- Update debian/changelog" cp ../changelog.old debian/changelog - dch --newversion $NEXT_RELEASE~$SVNTAG+${serie}1 Auto build from trunk + dch --newversion $NEXT_RELEASE~$SVNTAG-0${serie}1 Auto build from trunk echo " -- Build a package" debuild -S -sa From getxsick at codespeak.net Mon Mar 29 00:17:34 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 00:17:34 +0200 (CEST) Subject: [pypy-svn] r73054 - pypy/build/ubuntu/trunk Message-ID: <20100328221734.35318282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 00:17:32 2010 New Revision: 73054 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: Add dput command. Currently commented cause gpg-agent is still not installed. Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 00:17:32 2010 @@ -37,6 +37,7 @@ cd .. # upload + #dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${serie}1_source.changes done rm changelog.old From getxsick at codespeak.net Mon Mar 29 00:21:04 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 00:21:04 +0200 (CEST) Subject: [pypy-svn] r73055 - pypy/build/ubuntu/trunk Message-ID: <20100328222104.43FE4282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 00:21:02 2010 New Revision: 73055 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: add echo for uploading process Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 00:21:02 2010 @@ -36,7 +36,7 @@ debuild -S -sa cd .. - # upload + echo " -- Upload a package" #dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${serie}1_source.changes done From benjamin at codespeak.net Mon Mar 29 00:35:40 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 00:35:40 +0200 (CEST) Subject: [pypy-svn] r73056 - pypy/trunk/pypy/objspace/flow Message-ID: <20100328223540.083E2282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 00:35:39 2010 New Revision: 73056 Modified: pypy/trunk/pypy/objspace/flow/objspace.py Log: try to use the less hacky way of extracting a cell's contents Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Mon Mar 29 00:35:39 2010 @@ -230,9 +230,7 @@ if func.func_closure is None: closure = None else: - closure = [extract_cell_content(c, name, func) - for c, name in zip(func.func_closure, - func.func_code.co_freevars)] + closure = [extract_cell_content(c) for c in func.func_closure] # CallableFactory.pycall may add class_ to functions that are methods name = func.func_name class_ = getattr(func, 'class_', None) @@ -540,25 +538,27 @@ OverflowError) # for the float case del _add_exceptions, _add_except_ovf -def extract_cell_content(c, varname='?', func='?'): +def extract_cell_content(c): """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" - # yuk! this is all I could come up with that works in Python 2.2 too - class X(object): - def __cmp__(self, other): - self.other = other - return 0 - def __eq__(self, other): - self.other = other - return True - x = X() - x_cell, = (lambda: x).func_closure - x_cell == c try: - return x.other # crashes if the cell is actually empty + # This is simple on 2.6 + return getattr(c, "cell_contents") except AttributeError: - raise Exception("in %r, the free variable %r has no value" % ( - func, varname)) + class X(object): + def __cmp__(self, other): + self.other = other + return 0 + def __eq__(self, other): + self.other = other + return True + x = X() + x_cell, = (lambda: x).func_closure + x_cell == c + try: + return x.other # crashes if the cell is actually empty + except AttributeError: + raise ValueError("empty cell") def make_op(name, symbol, arity, specialnames): if hasattr(FlowObjSpace, name): From benjamin at codespeak.net Mon Mar 29 00:37:31 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 00:37:31 +0200 (CEST) Subject: [pypy-svn] r73057 - pypy/trunk/pypy/objspace/flow Message-ID: <20100328223731.58D64282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 00:37:29 2010 New Revision: 73057 Modified: pypy/trunk/pypy/objspace/flow/objspace.py Log: remove some old code Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Mon Mar 29 00:37:29 2010 @@ -511,23 +511,17 @@ lis.append(OverflowError) implicit_exceptions[name+"_ovf"] = lis -#for _err in IndexError, KeyError: -# _add_exceptions("""getitem setitem delitem""", _err) for _name in 'getattr', 'delattr': _add_exceptions(_name, AttributeError) for _name in 'iter', 'coerce': _add_exceptions(_name, TypeError) -del _name#, _err +del _name _add_exceptions("""div mod divmod truediv floordiv pow inplace_div inplace_mod inplace_divmod inplace_truediv inplace_floordiv inplace_pow""", ZeroDivisionError) _add_exceptions("""pow inplace_pow lshift inplace_lshift rshift inplace_rshift""", ValueError) -##_add_exceptions("""add sub mul truediv floordiv div mod divmod pow -## inplace_add inplace_sub inplace_mul inplace_truediv -## inplace_floordiv inplace_div inplace_mod inplace_divmod -## inplace_pow""", FloatingPointError) _add_exceptions("""truediv divmod inplace_add inplace_sub inplace_mul inplace_truediv inplace_floordiv inplace_div inplace_mod inplace_pow From getxsick at codespeak.net Mon Mar 29 00:52:08 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 00:52:08 +0200 (CEST) Subject: [pypy-svn] r73058 - pypy/build/ubuntu/trunk Message-ID: <20100328225208.EE301282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 00:52:07 2010 New Revision: 73058 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: Ooops. forgot to change distribution for each build. Also, need to use --force-distribution due to we run the script on 9.10 (and we build against upcoming 10.4) Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 00:52:07 2010 @@ -24,20 +24,21 @@ mv debian/ pypy-$NEXT_RELEASE~$SVNTAG cp pypy-$NEXT_RELEASE~$SVNTAG/debian/changelog changelog.old -for serie in lucid karmic jaunty +for dist in lucid karmic jaunty do - echo " - Preparing $serie package" + echo " - Preparing $dist package" cd pypy-$NEXT_RELEASE~$SVNTAG echo " -- Update debian/changelog" cp ../changelog.old debian/changelog - dch --newversion $NEXT_RELEASE~$SVNTAG-0${serie}1 Auto build from trunk + dch --newversion $NEXT_RELEASE~$SVNTAG-0${dist}1 --distribution $dist \ + --force-distribution Auto build from trunk echo " -- Build a package" debuild -S -sa cd .. echo " -- Upload a package" - #dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${serie}1_source.changes + #dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${dist}1_source.changes done rm changelog.old From benjamin at codespeak.net Mon Mar 29 01:39:36 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 01:39:36 +0200 (CEST) Subject: [pypy-svn] r73059 - pypy/trunk/pypy/objspace/std/test Message-ID: <20100328233936.06FE3282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 01:39:35 2010 New Revision: 73059 Modified: pypy/trunk/pypy/objspace/std/test/test_smallintobject.py Log: let's have some tests for small int with optimized add Modified: pypy/trunk/pypy/objspace/std/test/test_smallintobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_smallintobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_smallintobject.py Mon Mar 29 01:39:35 2010 @@ -8,6 +8,7 @@ from pypy.objspace.std.objspace import FailedToImplement from pypy.rlib.rarithmetic import r_uint +from pypy.objspace.std.test.test_intobject import AppTestInt from pypy.conftest import gettestobjspace class TestW_IntObject: @@ -223,3 +224,10 @@ f1 = wrapint(self.space, x) result = self.space.hex(f1) assert self.space.unwrap(result) == hex(x) + + +class AppTestSmallInt(AppTestInt): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.optimized_int_add" : True, + "objspace.std.withsmallint" : True}) From benjamin at codespeak.net Mon Mar 29 01:48:35 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 01:48:35 +0200 (CEST) Subject: [pypy-svn] r73060 - pypy/trunk/pypy/objspace/std/test Message-ID: <20100328234835.5D841282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 01:48:32 2010 New Revision: 73060 Modified: pypy/trunk/pypy/objspace/std/test/test_listobject.py Log: test for optimized list getitem 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 Mon Mar 29 01:48:32 2010 @@ -2,6 +2,7 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError +from pypy.conftest import gettestobjspace class TestW_ListObject: @@ -769,3 +770,18 @@ l = [1,2,3,4] l.__delslice__(0, 2) assert l == [3, 4] + + +class AppTestListFastSubscr: + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.optimized_list_getitem" : + True}) + + def test_getitem(self): + import operator + l = [0, 1, 2, 3, 4] + for i in xrange(5): + assert l[i] == i + assert l[3:] == [3, 4] + raises(TypeError, operator.getitem, l, "str") From benjamin at codespeak.net Mon Mar 29 01:51:41 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 01:51:41 +0200 (CEST) Subject: [pypy-svn] r73061 - pypy/trunk/pypy/objspace/std Message-ID: <20100328235141.415C9282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 01:51:39 2010 New Revision: 73061 Added: pypy/trunk/pypy/objspace/std/frame.py (contents, props changed) Modified: pypy/trunk/pypy/objspace/std/objspace.py Log: move creation of the StdObjSpaceFrame to a another file Added: pypy/trunk/pypy/objspace/std/frame.py ============================================================================== --- (empty file) +++ pypy/trunk/pypy/objspace/std/frame.py Mon Mar 29 01:51:39 2010 @@ -0,0 +1,199 @@ +"""StdObjSpace custom opcode implementations""" + +import operator + +from pypy.rlib.unroll import unrolling_iterable +from pypy.interpreter import pyframe, pyopcode, function +from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module +from pypy.objspace.std.multimethod import FailedToImplement + + +class BaseFrame(pyframe.PyFrame): + """These opcodes are always overridden.""" + + def LIST_APPEND(f, oparg, next_instr): + from pypy.objspace.std.listobject import W_ListObject + w = f.popvalue() + v = f.popvalue() + if type(v) is W_ListObject: + v.append(w) + else: + f.space.call_method(v, 'append', w) + + +def small_int_BINARY_ADD(f, oparg, next_instr): + from pypy.objspace.std.smallintobject import (W_SmallIntObject, + add__SmallInt_SmallInt) + w_2 = f.popvalue() + w_1 = f.popvalue() + if type(w_1) is W_SmallIntObject and type(w_2) is W_SmallIntObject: + try: + w_result = add__SmallInt_SmallInt(f.space, w_1, w_2) + except FailedToImplement: + w_result = f.space.add(w_1, w_2) + else: + w_result = f.space.add(w_1, w_2) + f.pushvalue(w_result) + + +def int_BINARY_ADD(f, oparg, next_instr): + from pypy.objspace.std.intobject import W_IntObject, add__Int_Int + w_2 = f.popvalue() + w_1 = f.popvalue() + if type(w_1) is W_IntObject and type(w_2) is W_IntObject: + try: + w_result = add__Int_Int(f.space, w_1, w_2) + except FailedToImplement: + w_result = f.space.add(w_1, w_2) + else: + w_result = f.space.add(w_1, w_2) + f.pushvalue(w_result) + + +def list_BINARY_SUBSCR(f, oparg, next_instr): + from pypy.objspace.std.intobject import W_IntObject + from pypy.objspace.std.listobject import W_ListObject + w_2 = f.popvalue() + w_1 = f.popvalue() + if type(w_1) is W_ListObject and type(w_2) is W_IntObject: + try: + w_result = w_1.wrappeditems[w_2.intval] + except IndexError: + raise OperationError(f.space.w_IndexError, + f.space.wrap("list index out of range")) + else: + w_result = f.space.getitem(w_1, w_2) + f.pushvalue(w_result) + +def CALL_LIKELY_BUILTIN(f, oparg, next_instr): + from pypy.objspace.std.dictmultiobject import W_DictMultiObject + w_globals = f.w_globals + num = oparg >> 8 + assert isinstance(w_globals, W_DictMultiObject) + w_value = w_globals.get_builtin_indexed(num) + if w_value is None: + builtins = f.get_builtin() + assert isinstance(builtins, Module) + w_builtin_dict = builtins.w_dict + assert isinstance(w_builtin_dict, W_DictMultiObject) + w_value = w_builtin_dict.get_builtin_indexed(num) + if w_value is None: + varname = OPTIMIZED_BUILTINS[num] + message = "global name '%s' is not defined" + raise operationerrfmt(f.space.w_NameError, + message, varname) + nargs = oparg & 0xff + w_function = w_value + try: + w_result = call_likely_builtin(f, w_function, nargs) + finally: + f.dropvalues(nargs) + f.pushvalue(w_result) + +def call_likely_builtin(f, w_function, nargs): + if isinstance(w_function, function.Function): + executioncontext = f.space.getexecutioncontext() + executioncontext.c_call_trace(f, w_function) + res = w_function.funccall_valuestack(nargs, f) + executioncontext.c_return_trace(f, w_function) + return res + args = f.make_arguments(nargs) + return f.space.call_args(w_function, args) + + +compare_table = [ + "lt", # "<" + "le", # "<=" + "eq", # "==" + "ne", # "!=" + "gt", # ">" + "ge", # ">=" + ] +unrolling_compare_ops = unrolling_iterable(enumerate(compare_table)) + +def fast_COMPARE_OP(f, testnum, next_instr): + from pypy.objspace.std.intobject import W_IntObject + w_2 = f.popvalue() + w_1 = f.popvalue() + w_result = None + if (type(w_2) is W_IntObject and type(w_1) is W_IntObject + and testnum < len(compare_table)): + for i, attr in unrolling_compare_ops: + if i == testnum: + op = getattr(operator, attr) + w_result = f.space.newbool(op(w_1.intval, + w_2.intval)) + break + else: + for i, attr in pyopcode.unrolling_compare_dispatch_table: + if i == testnum: + w_result = getattr(f, attr)(w_1, w_2) + break + else: + raise pyopcde.BytecodeCorruption, "bad COMPARE_OP oparg" + f.pushvalue(w_result) + + +def build_frame(space): + """Consider the objspace config and return a patched frame object.""" + class StdObjSpaceFrame(BaseFrame): + pass + if space.config.objspace.std.optimized_int_add: + if space.config.objspace.std.withsmallint: + StdObjSpaceFrame.BINARY_ADD = small_int_BINARY_ADD + else: + StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD + if space.config.objspace.std.optimized_list_getitem: + StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR + if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN: + StdObjSpaceFrame.CALL_LIKELY_BUILTIN = CALL_LIKELY_BUILTIN + if space.config.objspace.opcodes.CALL_METHOD: + from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD + StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD + StdObjSpaceFrame.CALL_METHOD = CALL_METHOD + if space.config.objspace.std.optimized_comparison_op: + StdObjSpaceFrame.COMPARE_OP = fast_COMPARE_OP + if space.config.objspace.std.logspaceoptypes: + StdObjSpace._space_op_types = [] + for name, new in get_logging(): + setattr(StdObjSpaceFrame, name, new) + return StdObjSpaceFrame + + +def get_logging(): + for name, func in pyframe.PyFrame.__dict__.iteritems(): + if hasattr(func, 'binop'): + operationname = func.binop + def make_opimpl(operationname): + def opimpl(f, *ignored): + operation = getattr(f.space, operationname) + w_2 = f.popvalue() + w_1 = f.popvalue() + if we_are_translated(): + s = operationname + ' ' + str(w_1) + ' ' + str(w_2) + else: + names = (w_1.__class__.__name__ + ' ' + + w_2.__class__.__name__) + s = operationname + ' ' + names + f._space_op_types.append(s) + w_result = operation(w_1, w_2) + f.pushvalue(w_result) + return func_with_new_name(opimpl, + "opcode_impl_for_%s" % operationname) + yield name, make_opimpl(operationname) + elif hasattr(func, 'unaryop'): + operationname = func.unaryop + def make_opimpl(operationname): + def opimpl(f, *ignored): + operation = getattr(f.space, operationname) + w_1 = f.popvalue() + if we_are_translated(): + s = operationname + ' ' + str(w_1) + else: + s = operationname + ' ' + w_1.__class__.__name__ + f._space_op_types.append(s) + w_result = operation(w_1) + f.pushvalue(w_result) + return func_with_new_name(opimpl, + "opcode_impl_for_%s" % operationname) + yield name, make_opimpl(operationname) Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Mon Mar 29 01:51:39 2010 @@ -2,24 +2,20 @@ from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError from pypy.interpreter.error import OperationError, operationerrfmt, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter import pyframe -from pypy.interpreter import function -from pypy.interpreter.pyopcode import unrolling_compare_dispatch_table, \ - BytecodeCorruption +from pypy.interpreter import pyframe, function from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized from pypy.interpreter.gateway import PyPyCacheDir -from pypy.tool.cache import Cache +from pypy.tool.cache import Cache from pypy.tool.sourcetools import func_with_new_name from pypy.objspace.std.model import W_Object, UnwrapError from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs from pypy.objspace.descroperation import DescrOperation, raiseattrerror -from pypy.objspace.std import stdtypedef +from pypy.objspace.std import stdtypedef, frame from pypy.rlib.rarithmetic import base_int from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.jit import hint -from pypy.rlib.unroll import unrolling_iterable import sys import os import __builtin__ @@ -31,18 +27,6 @@ _registered_implementations[implcls] = True -compare_table = [ - "lt", # "<" - "le", # "<=" - "eq", # "==" - "ne", # "!=" - "gt", # ">" - "ge", # ">=" - ] - -unrolling_compare_ops = unrolling_iterable( - enumerate(compare_table)) - ################################################################## class StdObjSpace(ObjSpace, DescrOperation): @@ -58,166 +42,7 @@ # Import all the object types and implementations self.model = StdTypeModel(self.config) - - class StdObjSpaceFrame(pyframe.PyFrame): - if self.config.objspace.std.optimized_int_add: - if self.config.objspace.std.withsmallint: - def BINARY_ADD(f, oparg, *ignored): - from pypy.objspace.std.smallintobject import \ - W_SmallIntObject, add__SmallInt_SmallInt - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_SmallIntObject and type(w_2) is W_SmallIntObject: - try: - w_result = add__SmallInt_SmallInt(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - else: - def BINARY_ADD(f, oparg, *ignored): - from pypy.objspace.std.intobject import \ - W_IntObject, add__Int_Int - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_IntObject and type(w_2) is W_IntObject: - try: - w_result = add__Int_Int(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - - if self.config.objspace.std.optimized_list_getitem: - def BINARY_SUBSCR(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_ListObject and type(w_2) is W_IntObject: - try: - w_result = w_1.wrappeditems[w_2.intval] - except IndexError: - raise OperationError(f.space.w_IndexError, - f.space.wrap("list index out of range")) - else: - w_result = f.space.getitem(w_1, w_2) - f.pushvalue(w_result) - - def LIST_APPEND(f, *ignored): - w = f.popvalue() - v = f.popvalue() - if type(v) is W_ListObject: - v.append(w) - else: - f.space.call_method(v, 'append', w) - - if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN: - def CALL_LIKELY_BUILTIN(f, oparg, *ignored): - from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module - from pypy.objspace.std.dictmultiobject import W_DictMultiObject - w_globals = f.w_globals - num = oparg >> 8 - assert isinstance(w_globals, W_DictMultiObject) - w_value = w_globals.get_builtin_indexed(num) - if w_value is None: - builtins = f.get_builtin() - assert isinstance(builtins, Module) - w_builtin_dict = builtins.w_dict - assert isinstance(w_builtin_dict, W_DictMultiObject) - w_value = w_builtin_dict.get_builtin_indexed(num) - ## if w_value is not None: - ## print "CALL_LIKELY_BUILTIN fast" - if w_value is None: - varname = OPTIMIZED_BUILTINS[num] - message = "global name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, - message, varname) - nargs = oparg & 0xff - w_function = w_value - try: - w_result = f.call_likely_builtin(w_function, nargs) - # XXX XXX fix the problem of resume points! - #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) - finally: - f.dropvalues(nargs) - f.pushvalue(w_result) - - def call_likely_builtin(f, w_function, nargs): - if isinstance(w_function, function.Function): - executioncontext = self.getexecutioncontext() - executioncontext.c_call_trace(f, w_function) - res = w_function.funccall_valuestack(nargs, f) - executioncontext.c_return_trace(f, w_function) - return res - args = f.make_arguments(nargs) - return f.space.call_args(w_function, args) - - if self.config.objspace.opcodes.CALL_METHOD: - # def LOOKUP_METHOD(...): - from pypy.objspace.std.callmethod import LOOKUP_METHOD - # def CALL_METHOD(...): - from pypy.objspace.std.callmethod import CALL_METHOD - - if self.config.objspace.std.optimized_comparison_op: - def COMPARE_OP(f, testnum, *ignored): - import operator - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = None - if (type(w_2) is W_IntObject and type(w_1) is W_IntObject - and testnum < len(compare_table)): - for i, attr in unrolling_compare_ops: - if i == testnum: - op = getattr(operator, attr) - w_result = f.space.newbool(op(w_1.intval, - w_2.intval)) - break - else: - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) - break - else: - raise BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) - - if self.config.objspace.std.logspaceoptypes: - _space_op_types = [] - for name, func in pyframe.PyFrame.__dict__.iteritems(): - if hasattr(func, 'binop'): - operationname = func.binop - def make_opimpl(operationname): - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_2 = f.popvalue() - w_1 = f.popvalue() - if we_are_translated(): - s = operationname + ' ' + str(w_1) + ' ' + str(w_2) - else: - s = operationname + ' ' + w_1.__class__.__name__ + ' ' + w_2.__class__.__name__ - f._space_op_types.append(s) - w_result = operation(w_1, w_2) - f.pushvalue(w_result) - return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) - locals()[name] = make_opimpl(operationname) - elif hasattr(func, 'unaryop'): - operationname = func.unaryop - def make_opimpl(operationname): - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_1 = f.popvalue() - if we_are_translated(): - s = operationname + ' ' + str(w_1) - else: - s = operationname + ' ' + w_1.__class__.__name__ - f._space_op_types.append(s) - w_result = operation(w_1) - f.pushvalue(w_result) - return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) - locals()[name] = make_opimpl(operationname) - - self.FrameClass = StdObjSpaceFrame + self.FrameClass = frame.build_frame(self) # store the dict class on the space to access it in various places from pypy.objspace.std import dictmultiobject From benjamin at codespeak.net Mon Mar 29 01:59:08 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 01:59:08 +0200 (CEST) Subject: [pypy-svn] r73062 - pypy/trunk/pypy/objspace/std Message-ID: <20100328235908.630FD282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 01:59:06 2010 New Revision: 73062 Modified: pypy/trunk/pypy/objspace/std/objspace.py Log: remove unused constant Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Mon Mar 29 01:59:06 2010 @@ -33,8 +33,6 @@ """The standard object space, implementing a general-purpose object library in Restricted Python.""" - PACKAGE_PATH = 'objspace.std' - def initialize(self): "NOT_RPYTHON: only for initializing the space." self._typecache = Cache() From benjamin at codespeak.net Mon Mar 29 02:04:10 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 02:04:10 +0200 (CEST) Subject: [pypy-svn] r73063 - pypy/trunk/pypy/objspace/std Message-ID: <20100329000410.25D81282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 02:04:08 2010 New Revision: 73063 Modified: pypy/trunk/pypy/objspace/std/frame.py Log: add imports Modified: pypy/trunk/pypy/objspace/std/frame.py ============================================================================== --- pypy/trunk/pypy/objspace/std/frame.py (original) +++ pypy/trunk/pypy/objspace/std/frame.py Mon Mar 29 02:04:08 2010 @@ -4,6 +4,7 @@ from pypy.rlib.unroll import unrolling_iterable from pypy.interpreter import pyframe, pyopcode, function +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module from pypy.objspace.std.multimethod import FailedToImplement From benjamin at codespeak.net Mon Mar 29 02:05:06 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 02:05:06 +0200 (CEST) Subject: [pypy-svn] r73064 - pypy/trunk/pypy/objspace/std Message-ID: <20100329000506.53121282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 02:05:04 2010 New Revision: 73064 Modified: pypy/trunk/pypy/objspace/std/objspace.py Log: remove unused _typecache attribute Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Mon Mar 29 02:05:04 2010 @@ -35,8 +35,6 @@ def initialize(self): "NOT_RPYTHON: only for initializing the space." - self._typecache = Cache() - # Import all the object types and implementations self.model = StdTypeModel(self.config) From xoraxax at codespeak.net Mon Mar 29 02:17:36 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 02:17:36 +0200 (CEST) Subject: [pypy-svn] r73065 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100329001736.D687E282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 02:17:35 2010 New Revision: 73065 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h pypy/branch/cpython-extension/pypy/module/cpyext/macros.py pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: RPythonify further. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 02:17:35 2010 @@ -98,6 +98,7 @@ def _freeze_(self): return True + @specialize.memo() def get_llhelper(self, space): llh = getattr(self, '_llhelper', None) if llh is None: @@ -134,22 +135,23 @@ names = api_function.argnames types_names_enum_ui = unrolling_iterable(enumerate(zip(api_function.argtypes, names, [name.startswith("w_") for name in names]))) + @specialize.argtype(1) def unwrapper(space, *args): newargs = () to_decref = () for i, (typ, name, is_wrapped) in types_names_enum_ui: + input_arg = args[i] if typ is PyObject: - if (isinstance(args[i], W_Root) and - not is_wrapped): - arg = make_ref(space, args[i]) + if not is_wrapped and (input_arg is None + or isinstance(input_arg, W_Root)): + arg = make_ref(space, input_arg) to_decref += (arg, ) - elif (not isinstance(args[i], W_Root) and - is_wrapped): - arg = from_ref(space, args[i]) + elif is_wrapped and not isinstance(input_arg, W_Root): + arg = from_ref(space, input_arg) else: - arg = args[i] + arg = input_arg else: - arg = args[i] + arg = input_arg newargs += (arg, ) try: try: @@ -186,6 +188,18 @@ def decorate(func): FUNCTIONS_C[func.func_name] = None return decorate +def get_padded_type(T): + fields = T._flds.copy() + hints = T._hints.copy() + del hints["fieldoffsets"] + pad_fields = [] + new_fields = [] + for name in T._names: + new_fields.append((name, fields[name])) + new_fields.append(("custom_padding", lltype.Array(lltype.Char))) + hints["padding"] = hints["padding"] + ("custom_padding", ) + return lltype.Struct(hints["c_name"], hints=hints, *new_fields) + def cpython_struct(name, fields, forward=None): configname = name.replace(' ', '__') @@ -217,10 +231,11 @@ PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyObject)) PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) +PyObjectStructPadded = lltype.ForwardReference() PyStringObjectStruct = lltype.ForwardReference() PyStringObject = lltype.Ptr(PyStringObjectStruct) -PyStringObjectFields = PyVarObjectFields + \ +PyStringObjectFields = PyObjectFields + \ (("buffer", rffi.CCHARP), ("size", Py_ssize_t)) cpython_struct("PyStringObject", PyStringObjectFields, PyStringObjectStruct) @@ -228,6 +243,7 @@ for name, TYPE in rffi_platform.configure(CConfig).iteritems(): if name in TYPES: TYPES[name].become(TYPE) + PyObjectStructPadded.become(get_padded_type(PyObjectStruct)) class NullPointerException(Exception): @@ -236,33 +252,15 @@ class InvalidPointerException(Exception): pass -def get_padded_type(T, size): - fields = T._flds.copy() - hints = T._hints.copy() - hints["size"] = size - del hints["fieldoffsets"] - pad_fields = [] - new_fields = [] - for name in T._names: - new_fields.append((name, fields[name])) - for i in xrange(size - rffi.sizeof(T)): - new_fields.append(("custom%i" % (i, ), lltype.Char)) - hints["padding"] = hints["padding"] + tuple(pad_fields) - return lltype.Struct(hints["c_name"], hints=hints, *new_fields) - def debug_refcount(*args, **kwargs): - if DEBUG_REFCOUNT: - frame_stackdepth = kwargs.pop("frame_stackdepth", 2) - assert not kwargs - frame = sys._getframe(frame_stackdepth) - print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), - for arg in args: - print >>sys.stderr, arg, - print >>sys.stderr - -if not DEBUG_REFCOUNT: - def debug_refcount(arg0, arg1, arg2, arg3=None, arg4=None, frame_stackdepth=None): - pass + frame_stackdepth = kwargs.pop("frame_stackdepth", 2) + assert not kwargs + frame = sys._getframe(frame_stackdepth) + print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), + for arg in args: + print >>sys.stderr, arg, + print >>sys.stderr + def make_ref(space, w_obj, borrowed=False, steal=False): from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF @@ -270,13 +268,14 @@ return lltype.nullptr(PyObject.TO) assert isinstance(w_obj, W_Root) state = space.fromcache(State) - py_obj = state.py_objects_w2r.get(w_obj, None) - if py_obj is None: + py_obj = state.py_objects_w2r.get(w_obj, lltype.nullptr(PyObject.TO)) + if not py_obj: from pypy.module.cpyext.typeobject import allocate_type_obj,\ W_PyCTypeObject, W_PyCObject w_type = space.type(w_obj) if space.is_w(w_type, space.w_type): - py_obj = allocate_type_obj(space, w_obj) + pto = allocate_type_obj(space, w_obj) + py_obj = rffi.cast(PyObject, pto) # c_ob_type and c_ob_refcnt are set by allocate_type_obj elif isinstance(w_obj, W_PyCObject): w_type = space.type(w_obj) @@ -284,17 +283,18 @@ pto = w_type.pto # Don't increase refcount for non-heaptypes # Py_INCREF(space, pto) - basicsize = pto._obj.c_tp_basicsize - T = get_padded_type(PyObject.TO, basicsize) - py_obj = lltype.malloc(T, flavor="raw", zero=True) + basicsize = pto.c_tp_basicsize + py_obj_pad = lltype.malloc(PyObjectStructPadded, basicsize, + flavor="raw", zero=True) + py_obj = rffi.cast(PyObject, py_obj_pad) py_obj.c_ob_refcnt = 1 py_obj.c_ob_type = rffi.cast(PyObject, pto) elif isinstance(w_obj, W_StringObject): - py_obj = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True) - py_obj.c_size = len(space.str_w(w_obj)) - py_obj.c_buffer = lltype.nullptr(rffi.CCHARP.TO) + py_obj_str = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True) + py_obj_str.c_size = len(space.str_w(w_obj)) + py_obj_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO) pto = make_ref(space, space.w_str) - py_obj = rffi.cast(PyObject, py_obj) + py_obj = rffi.cast(PyObject, py_obj_str) py_obj.c_ob_refcnt = 1 py_obj.c_ob_type = rffi.cast(PyObject, pto) else: @@ -303,8 +303,8 @@ pto = make_ref(space, space.type(w_obj)) py_obj.c_ob_type = rffi.cast(PyObject, pto) ptr = rffi.cast(ADDR, py_obj) - py_obj = rffi.cast(PyObject, py_obj) - debug_refcount("MAKREF", py_obj, w_obj) + if DEBUG_REFCOUNT: + debug_refcount("MAKREF", py_obj, w_obj) state.py_objects_w2r[w_obj] = py_obj state.py_objects_r2w[ptr] = w_obj if borrowed and ptr not in state.borrowed_objects: @@ -611,14 +611,20 @@ state.check_and_raise_exception() def make_generic_cpy_call_func(decref_args): + @specialize.memo() + def get_args_count(functype): + return unrolling_iterable(range(len(functype.ARGS))) + @specialize.argtype(2) def generic_cpy_call(space, func, *args): from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_Occurred boxed_args = () - for arg in args: # XXX UI needed - if isinstance(arg, W_Root) or arg is None: + args_count_ui = get_args_count(lltype.typeOf(func).TO) + for i in args_count_ui: # this gives a warning + arg = args[i] + if not rffi._isllptr(arg) and (isinstance(arg, W_Root) or arg is None): boxed_args += (make_ref(space, arg), ) else: boxed_args += (arg, ) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/stringobject.h Mon Mar 29 02:17:35 2010 @@ -8,7 +8,7 @@ #endif typedef struct { - PyObject_VAR_HEAD + PyObject_HEAD char* buffer; Py_ssize_t size; } PyStringObject; Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Mon Mar 29 02:17:35 2010 @@ -11,7 +11,8 @@ def Py_DECREF(space, obj): from pypy.module.cpyext.typeobject import string_dealloc obj.c_ob_refcnt -= 1 - debug_refcount("DECREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) + if DEBUG_REFCOUNT: + debug_refcount("DECREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) if obj.c_ob_refcnt == 0: state = space.fromcache(State) ptr = rffi.cast(ADDR, obj) @@ -48,7 +49,8 @@ def Py_INCREF(space, obj): obj.c_ob_refcnt += 1 assert obj.c_ob_refcnt > 0 - debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) + if DEBUG_REFCOUNT: + debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) @cpython_api([PyObject], lltype.Void) def Py_XINCREF(space, obj): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Mon Mar 29 02:17:35 2010 @@ -13,7 +13,7 @@ @cpython_api([], PyObject, borrowed=True) def PyErr_Occurred(space): state = space.fromcache(State) - register_container(space, None) + register_container(space, lltype.nullptr(PyObject.TO)) return state.exc_value @cpython_api([], lltype.Void) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_api.py Mon Mar 29 02:17:35 2010 @@ -10,7 +10,7 @@ assert isinstance(w_arg, W_Root) @api.cpython_api([PyObject], lltype.Void) def PyPy_GetReference(space, arg): - assert lltype.typeOf(arg) is PyObject + assert lltype.typeOf(arg) == PyObject class BaseApiTest: def setup_class(cls): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Mon Mar 29 02:17:35 2010 @@ -27,9 +27,7 @@ assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject] def test_padding(self): - T = api.get_padded_type(api.PyObject.TO, 42) - assert rffi.sizeof(T) == 42 - print T + T = api.get_padded_type(api.PyObject.TO) class AppTestApi: def setup_class(cls): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 02:17:35 2010 @@ -219,6 +219,8 @@ space.is_w(w_obj, space.w_object)): base_pyo = make_ref(space, space.w_object) base = pto.c_tp_base = rffi.cast(PyTypeObjectPtr, base_pyo) + else: + base_pyo = rffi.cast(PyObject, base) if base and not base.c_tp_flags & Py_TPFLAGS_READY: PyPyType_Ready(space, base, None) if base and not pto.c_ob_type: # will be filled later @@ -228,7 +230,7 @@ if not base: bases = space.newtuple([]) else: - bases = space.newtuple([from_ref(space, base)]) + bases = space.newtuple([from_ref(space, base_pyo)]) pto.c_tp_bases = make_ref(space, bases) if w_obj is None: PyPyType_Register(space, pto) From xoraxax at codespeak.net Mon Mar 29 02:31:18 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 02:31:18 +0200 (CEST) Subject: [pypy-svn] r73066 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329003118.BF28D282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 02:31:17 2010 New Revision: 73066 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Inline unwrapper instead of the function, rework slotdefs and rpythonify them. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Mon Mar 29 02:31:17 2010 @@ -1,7 +1,6 @@ from pypy.interpreter.mixedmodule import MixedModule from pypy.rlib.objectmodel import we_are_translated from pypy.module.cpyext.state import State -from pypy.module.cpyext.slotdefs import init_slotdefs from pypy.module.cpyext import api @@ -18,7 +17,6 @@ state = self.space.fromcache(State) if not self.space.config.translating: state.api_lib = str(api.build_bridge(self.space)) - state.slotdefs = init_slotdefs(self.space) else: api.setup_library(self.space) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 02:31:17 2010 @@ -125,8 +125,6 @@ def decorate(func): api_function = ApiFunction(argtypes, restype, func, borrowed, error) func.api_func = api_function - # the function is always wrapped so lets inline it into the wrapper - func._always_inline_ = True if error is _NOT_SPECIFIED: raise ValueError("function %s has no return value for exceptions" @@ -174,6 +172,7 @@ Py_DECREF(space, arg) unwrapper.func = func unwrapper.api_func = api_function + unwrapper._always_inline_ = True return unwrapper unwrapper_True = make_unwrapper(True) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Mon Mar 29 02:31:17 2010 @@ -7,6 +7,7 @@ ternaryfunc from pypy.module.cpyext.state import State from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.rlib.unroll import unrolling_iterable space = None @@ -100,7 +101,7 @@ # Copy new slotdefs from typeobject.c # Remove comments # Done. -slotdefs = """ +slotdefs_str = """ static slotdef slotdefs[] = { SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, "x.__len__() <==> len(x)"), @@ -293,14 +294,9 @@ }; """ for regex, repl in slotdef_replacements: - slotdefs = re.sub(regex, repl, slotdefs) -def init_slotdefs(space_): - global space - space = space_ - try: - return eval(slotdefs) - finally: - space = None + slotdefs_str = re.sub(regex, repl, slotdefs_str) + +slotdefs = unrolling_iterable(eval(slotdefs_str)) if __name__ == "__main__": - print slotdefs + print slotdefs_str Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 02:31:17 2010 @@ -62,7 +62,7 @@ def add_operators(space, dict_w, pto): # XXX support PyObject_HashNotImplemented state = space.fromcache(State) - for method_name, slot_name, _, wrapper_func, wrapper_func_kwds, doc in state.slotdefs: # XXX use UI + for method_name, slot_name, _, wrapper_func, wrapper_func_kwds, doc in slotdefs: if method_name in dict_w: continue # XXX is this rpython? From cfbolz at codespeak.net Mon Mar 29 14:14:25 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 14:14:25 +0200 (CEST) Subject: [pypy-svn] r73067 - pypy/branch/reduce-instance-size-experiments Message-ID: <20100329121425.6BAFB282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 14:14:20 2010 New Revision: 73067 Added: pypy/branch/reduce-instance-size-experiments/ - copied from r73066, pypy/trunk/ Log: a branch where I want to play some more with making instances even smaller From benjamin at codespeak.net Mon Mar 29 15:44:41 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 15:44:41 +0200 (CEST) Subject: [pypy-svn] r73068 - pypy/trunk/pypy/objspace/flow Message-ID: <20100329134441.CDB01282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 15:44:39 2010 New Revision: 73068 Modified: pypy/trunk/pypy/objspace/flow/objspace.py Log: fix version in comment Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Mon Mar 29 15:44:39 2010 @@ -536,7 +536,7 @@ """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" try: - # This is simple on 2.6 + # This is simple on 2.5 return getattr(c, "cell_contents") except AttributeError: class X(object): From cfbolz at codespeak.net Mon Mar 29 15:52:28 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 15:52:28 +0200 (CEST) Subject: [pypy-svn] r73069 - in pypy/branch/reduce-instance-size-experiments/pypy/rlib: . test Message-ID: <20100329135228.1F7F8282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 15:52:26 2010 New Revision: 73069 Added: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py (contents, props changed) pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py (contents, props changed) Log: Add a mechanism for tagging and untagging pointers fully under the programmers control. Added: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py ============================================================================== --- (empty file) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py Mon Mar 29 15:52:26 2010 @@ -0,0 +1,154 @@ +""" Contains a mechanism for turning any class instance and any integer into a +pointer-like thing. Gives full control over pointer tagging, i.e. there won't +be tag checks everywhere in the C code. """ + +import sys +from pypy.annotation import model as annmodel +from pypy.tool.pairtype import pairtype +from pypy.rpython.extregistry import ExtRegistryEntry +from pypy.rpython.rclass import getinstancerepr +from pypy.rpython.rmodel import Repr +from pypy.rpython.lltypesystem.lloperation import llop +from pypy.rpython.lltypesystem.rclass import OBJECTPTR +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.error import TyperError + + + +def erase(x): + """Creates an 'erased' object that contains a reference to 'x'. Nothing can + be done with this object, except calling unerase(y, ) on it. + x needs to be either an instance or an integer fitting into 31/63 bits.""" + if isinstance(x, int): + res = 2 * x + 1 + if res > sys.maxint or res < -sys.maxint - 1: + raise OverflowError + return Erased(x) + +def unerase(y, type): + """Turn an erased object back into an object of type 'type'.""" + if y._x is None: + return None + assert isinstance(y._x, type) + return y._x + +def is_integer(e): + """Gives information whether the erased argument is a tagged integer or not.""" + return isinstance(e._x, int) + + +# ---------- implementation-specific ---------- + +class Erased(object): + def __init__(self, x): + self._x = x + +class Entry(ExtRegistryEntry): + _about_ = erase + + def compute_result_annotation(self, s_obj): + return someErased + + def specialize_call(self, hop): + return hop.r_result.specialize_call(hop) + +class Entry(ExtRegistryEntry): + _about_ = unerase + + def compute_result_annotation(self, s_obj, s_type): + assert s_type.is_constant() + if s_type.const is int: + return annmodel.SomeInteger() + assert isinstance(s_type, annmodel.SomePBC) + assert len(s_type.descriptions) == 1 + clsdef = s_type.descriptions.keys()[0].getuniqueclassdef() + return annmodel.SomeInstance(clsdef) + + def specialize_call(self, hop): + v, t = hop.inputargs(hop.args_r[0], lltype.Void) + if isinstance(hop.s_result, annmodel.SomeInteger): + c_one = hop.inputconst(lltype.Signed, 1) + vi = hop.genop('cast_ptr_to_int', [v], resulttype=lltype.Signed) + return hop.genop('int_rshift', [vi, c_one], resulttype=lltype.Signed) + return hop.genop('cast_pointer', [v], resulttype = hop.r_result) + +class Entry(ExtRegistryEntry): + _about_ = is_integer + + def compute_result_annotation(self, s_obj): + return annmodel.SomeBool() + + def specialize_call(self, hop): + v, = hop.inputargs(hop.args_r[0]) + c_one = hop.inputconst(lltype.Signed, 1) + vi = hop.genop('cast_ptr_to_int', [v], resulttype=lltype.Signed) + vb = hop.genop('int_and', [vi, c_one], resulttype=lltype.Signed) + return hop.genop('int_is_true', [vb], resulttype=lltype.Bool) + + +class Entry(ExtRegistryEntry): + _type_ = Erased + + def compute_annotation(self): + from pypy.rlib import _jit_vref + s_obj = self.bookkeeper.immutablevalue(self.instance._x) + return someErased + +# annotation and rtyping support + +class SomeErased(annmodel.SomeObject): + + def __init__(self): + pass + + def can_be_none(self): + return False # cannot be None, but can contain a None + + def rtyper_makerepr(self, rtyper): + return ErasedRepr(rtyper) + + def rtyper_makekey(self): + return self.__class__, + +someErased = SomeErased() + +class __extend__(pairtype(SomeErased, SomeErased)): + + def union((serased1, serased2)): + return serased1 + + +class ErasedRepr(Repr): + lowleveltype = OBJECTPTR + def __init__(self, rtyper): + self.rtyper = rtyper + + def specialize_call(self, hop): + s_arg, = hop.args_s + if isinstance(s_arg, annmodel.SomeInstance): + r_generic_object = getinstancerepr(hop.rtyper, None) + hop.exception_cannot_occur() + [v] = hop.inputargs(r_generic_object) # might generate a cast_pointer + return v + else: + assert isinstance(s_arg, annmodel.SomeInteger) + v_value = hop.inputarg(lltype.Signed, arg=0) + c_one = hop.inputconst(lltype.Signed, 1) + hop.exception_is_here() + v2 = hop.genop('int_lshift_ovf', [v_value, c_one], + resulttype = lltype.Signed) + v2p1 = hop.genop('int_add', [v2, c_one], + resulttype = lltype.Signed) + v_instance = hop.genop('cast_int_to_ptr', [v2p1], + resulttype = self.lowleveltype) + return v_instance + + + def convert_const(self, value): + if isinstance(value._x, int): + return lltype.cast_int_to_ptr(self.lowleveltype, value._x * 2 + 1) + else: + r_generic_object = getinstancerepr(self.rtyper, None) + v = r_generic_object.convert_const(value._x) + return v + Added: pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py ============================================================================== --- (empty file) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py Mon Mar 29 15:52:26 2010 @@ -0,0 +1,119 @@ +import py +import sys +from pypy.rlib.rerased import erase, unerase, is_integer, SomeErased +from pypy.annotation import model as annmodel +from pypy.annotation.annrpython import RPythonAnnotator +from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.lltypesystem.rclass import OBJECTPTR +from pypy.rpython.lltypesystem import lltype + + +class X(object): + pass + +class Y(X): + pass + +class Z(X): + pass + + +def test_simple(): + x1 = X() + e = erase(x1) + assert is_integer(e) is False + assert unerase(e, X) is x1 + +def test_simple_none(): + e = erase(None) + assert unerase(e, X) is None + +def test_simple_int(): + e = erase(15) + assert is_integer(e) is True + assert unerase(e, int) == 15 + +def test_simple_int_overflow(): + py.test.raises(OverflowError, erase, sys.maxint) + py.test.raises(OverflowError, erase, -sys.maxint) + +def test_annotate_1(): + def f(): + return erase(X()) + a = RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, SomeErased) + +def test_annotate_2(): + def f(): + x1 = X() + e = erase(x1) + assert not is_integer(e) + x2 = unerase(e, X) + return x2 + a = RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeInstance) + assert s.classdef == a.bookkeeper.getuniqueclassdef(X) + +def test_annotate_3(): + def f(): + e = erase(16) + assert is_integer(e) + x2 = unerase(e, int) + return x2 + a = RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeInteger) + +def test_rtype_1(): + def f(): + return erase(X()) + x = interpret(f, []) + assert lltype.typeOf(x) == OBJECTPTR + +def test_rtype_2(): + def f(): + x1 = X() + e = erase(x1) + assert not is_integer(e) + x2 = unerase(e, X) + return x2 + x = interpret(f, []) + assert lltype.castable(OBJECTPTR, lltype.typeOf(x)) > 0 + +def test_rtype_3(): + def f(): + e = erase(16) + assert is_integer(e) + x2 = unerase(e, int) + return x2 + x = interpret(f, []) + assert x == 16 + + +def test_prebuilt_erased(): + e1 = erase(16) + x1 = X() + e2 = erase(x1) + + def f(): + assert is_integer(e1) + assert not is_integer(e2) + x2 = unerase(e1, int) + return x2 + x = interpret(f, []) + assert x == 16 + +def test_overflow(): + def f(i): + try: + e = erase(i) + except OverflowError: + return -1 + assert is_integer(e) + return unerase(e, int) + x = interpret(f, [16]) + assert x == 16 + x = interpret(f, [sys.maxint]) + assert x == -1 From arigo at codespeak.net Mon Mar 29 16:02:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 16:02:41 +0200 (CEST) Subject: [pypy-svn] r73070 - pypy/branch/stackovf Message-ID: <20100329140241.737AD282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 16:02:39 2010 New Revision: 73070 Added: pypy/branch/stackovf/ - copied from r73069, pypy/trunk/ Log: A branch in which to have a real StackOverflow exception in RPython. From cfbolz at codespeak.net Mon Mar 29 16:37:22 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 16:37:22 +0200 (CEST) Subject: [pypy-svn] r73071 - in pypy/branch/reduce-instance-size-experiments/pypy: config interpreter objspace/std objspace/std/test rlib Message-ID: <20100329143722.270D7282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 16:37:21 2010 New Revision: 73071 Modified: pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py pypy/branch/reduce-instance-size-experiments/pypy/interpreter/baseobjspace.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py Log: use the type erasure code to unbox ints that are stored into instances Modified: pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py Mon Mar 29 16:37:21 2010 @@ -223,6 +223,11 @@ BoolOption("withsharingdict", "use dictionaries that share the keys part", default=False), + BoolOption("withsharingtaggingdict", + "use dictionaries that share the keys part and use tagged integers inside them", + default=False, + requires=[("objspace.std.withsharingdict", True), + ("translation.taggedpointers", True)]), BoolOption("withdictmeasurement", "create huge files with masses of information " Modified: pypy/branch/reduce-instance-size-experiments/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/interpreter/baseobjspace.py Mon Mar 29 16:37:21 2010 @@ -231,6 +231,8 @@ full_exceptions = True # full support for exceptions (normalization & more) + roottype = W_Root # for some tests + def __init__(self, config=None): "NOT_RPYTHON: Basic initialization of objects." self.fromcache = InternalSpaceCache(self).getorbuild Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 16:37:21 2010 @@ -50,6 +50,26 @@ def size_estimate(self): return self._size_estimate >> NUM_DIGITS +def erase(space, w_value): + if not space.config.objspace.std.withsharingtaggingdict: + return w_value + from pypy.rlib.rerased import erase + if space.is_true(space.isinstance(w_value, space.w_int)): + try: + return erase(space.int_w(w_value)) + except OverflowError: + pass + return erase(w_value) + +def unerase(space, erased): + if not space.config.objspace.std.withsharingtaggingdict: + return erased + from pypy.rlib.rerased import unerase, is_integer + if is_integer(erased): + return space.wrap(unerase(erased, int)) + return unerase(erased, space.roottype) + + class State(object): def __init__(self, space): self.empty_structure = SharedStructure() @@ -77,7 +97,7 @@ i = self.structure.lookup_position(lookup) if i == -1: return None - return self.entries[i] + return unerase(self.space, self.entries[i]) def impl_setitem(self, w_key, w_value): space = self.space @@ -88,9 +108,10 @@ @unroll_safe def impl_setitem_str(self, key, w_value, shadows_type=True): + e_value = erase(self.space, w_value) i = self.structure.lookup_position(key) if i != -1: - self.entries[i] = w_value + self.entries[i] = e_value return new_structure = self.structure.get_next_structure(key) if new_structure.length > len(self.entries): @@ -99,7 +120,7 @@ new_entries[i] = self.entries[i] self.entries = new_entries - self.entries[new_structure.length - 1] = w_value + self.entries[new_structure.length - 1] = e_value assert self.structure.length + 1 == new_structure.length self.structure = new_structure @@ -118,7 +139,7 @@ for i in range(pos, struct_len - 1): self.entries[i] = self.entries[i + 1] # don't make the entries list shorter, new keys might be added soon - self.entries[struct_len - 1] = None + self.entries[struct_len - 1] = erase(self.space, None) structure = self.structure keys = [None] * num_back for i in range(num_back): @@ -146,11 +167,14 @@ for (key, item) in self.structure.keys.iteritems()] def impl_values(self): - return self.entries[:self.structure.length] + return [unerase(self.space, self.entries[i]) + for i in range(self.structure.length)] def impl_items(self): space = self.space - return [space.newtuple([space.wrap(key), self.entries[item]]) + return [space.newtuple([ + space.wrap(key), + unerase(self.space, self.entries[item])]) for (key, item) in self.structure.keys.iteritems()] def impl_clear(self): space = self.space @@ -159,7 +183,8 @@ def _as_rdict(self): r_dict_content = self.initialize_as_rdict() for k, i in self.structure.keys.items(): - r_dict_content[self.space.wrap(k)] = self.entries[i] + r_dict_content[self.space.wrap(k)] = unerase( + self.space, self.entries[i]) self._clear_fields() return self @@ -176,7 +201,7 @@ implementation = self.dictimplementation assert isinstance(implementation, SharedDictImplementation) for key, index in self.iterator: - w_value = implementation.entries[index] - return self.space.wrap(key), w_value + e_value = implementation.entries[index] + return self.space.wrap(key), unerase(self.space, e_value) else: return None, None Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py Mon Mar 29 16:37:21 2010 @@ -529,6 +529,22 @@ a.abc = 12 a.__dict__.items() == [("abc", 12)] +class TestW_DictSharingTagging(TestW_DictObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withsharingtaggingdict": True}) + +class AppTest_DictSharing(AppTest_DictObject): + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.withsharingtaggingdict": True}) + + def test_tagging(self): + # slightly evil way to test this + class A(object): + pass + a = A() + a.x = x = 1231 + assert a.x is not x + class AppTestModuleDict(object): def setup_class(cls): @@ -558,6 +574,7 @@ # the minimal 'space' needed to use a W_DictMultiObject class FakeSpace: + roottype = object def hash_w(self, obj): return hash(obj) def unwrap(self, x): @@ -576,9 +593,13 @@ def type(self, w_obj): return type(w_obj) w_str = str + w_int = int def str_w(self, string): assert isinstance(string, str) return string + def int_w(self, obj): + assert isinstance(obj, int) + return obj def wrap(self, obj): return obj @@ -615,6 +636,7 @@ class std: withdictmeasurement = False withsharingdict = False + withsharingtaggingdict = False withsmalldicts = False withcelldict = False withshadowtracking = False Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py Mon Mar 29 16:37:21 2010 @@ -1,6 +1,7 @@ import py from pypy.conftest import gettestobjspace from pypy.objspace.std.sharingdict import SharedStructure, NUM_DIGITS, SharedDictImplementation +from pypy.objspace.std.sharingdict import erase, unerase from pypy.interpreter import gateway from pypy.objspace.std.test.test_dictmultiobject import FakeSpace @@ -30,6 +31,9 @@ assert empty_structure.other_structs.get("a").size_estimate() == 6 assert empty_structure.other_structs.get("x").size_estimate() == 2 +def unerase_entries(space, d): + return [unerase(space, e) for e in d.entries] + def test_delete(): space = FakeSpace() d = SharedDictImplementation(space) @@ -38,7 +42,7 @@ d.setitem_str("c", 3) d.delitem("b") assert d.r_dict_content is None - assert d.entries == [1, 3, None] + assert unerase_entries(space, d) == [1, 3, None] assert d.structure.keys == {"a": 0, "c": 1} assert d.getitem("a") == 1 assert d.getitem("c") == 3 @@ -46,11 +50,11 @@ py.test.raises(KeyError, d.delitem, "b") d.delitem("c") - assert d.entries == [1, None, None] + assert unerase_entries(space, d) == [1, None, None] assert d.structure.keys == {"a": 0} d.delitem("a") - assert d.entries == [None, None, None] + assert unerase_entries(space, d) == [None, None, None] assert d.structure.keys == {} d = SharedDictImplementation(space) @@ -64,5 +68,5 @@ d.setitem_str("h", 8) d.setitem_str("i", 9) d.delitem("d") - assert d.entries == [1, 2, 3, 5, 6, 7, 8, 9, None] + assert unerase_entries(space, d) == [1, 2, 3, 5, 6, 7, 8, 9, None] assert d.structure.keys == {"a": 0, "b": 1, "c": 2, "e": 3, "f": 4, "g": 5, "h": 6, "i": 7} Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py Mon Mar 29 16:37:21 2010 @@ -42,6 +42,8 @@ class Erased(object): def __init__(self, x): self._x = x + def __repr__(self): + return "Erased(%r)" % (self._x, ) class Entry(ExtRegistryEntry): _about_ = erase From xoraxax at codespeak.net Mon Mar 29 16:38:13 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 16:38:13 +0200 (CEST) Subject: [pypy-svn] r73072 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329143813.7BAA8282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 16:38:12 2010 New Revision: 73072 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Log: Cast correctly here. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Mon Mar 29 16:38:12 2010 @@ -38,13 +38,13 @@ @cpython_api([PyObject], rffi.CCHARP, error=0) def PyString_AsString(space, ref): - ref = rffi.cast(PyStringObject, ref) - if not ref.c_buffer: + ref_str = rffi.cast(PyStringObject, ref) + if not ref_str.c_buffer: # copy string buffer w_str = from_ref(space, ref) s = space.str_w(w_str) - ref.c_buffer = rffi.str2charp(s) - return ref.c_buffer + ref_str.c_buffer = rffi.str2charp(s) + return ref_str.c_buffer @cpython_api([PyObject], Py_ssize_t, error=-1) def PyString_Size(space, ref): From xoraxax at codespeak.net Mon Mar 29 16:38:38 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 16:38:38 +0200 (CEST) Subject: [pypy-svn] r73073 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329143838.0B4F6282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 16:38:36 2010 New Revision: 73073 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: Add casts and missing self. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Mon Mar 29 16:38:36 2010 @@ -34,7 +34,8 @@ self.space = space self.ml = ml self.name = rffi.charp2str(ml.c_ml_name) - self.w_objclass = from_ref(space, pto) + pyo = rffi.cast(PyObject, pto) + self.w_objclass = from_ref(space, pyo) def __repr__(self): return "" % (self.name, self.w_objclass.getname(self.space, '?')) @@ -52,14 +53,15 @@ self.wrapper_func_kwds = wrapper_func_kwds self.doc = doc self.func = func - self.w_objclass = from_ref(space, pto) + pyo = rffi.cast(PyObject, pto) + self.w_objclass = from_ref(space, pyo) def call(self, w_self, w_args, w_kw): if self.wrapper_func is None: assert self.wrapper_func_kwds is not None return self.wrapper_func_kwds(self.space, w_self, w_args, self.func, w_kw) if self.space.is_true(w_kw): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(self.space.w_TypeError, "wrapper %s doesn't take any keyword arguments", self.method_name) return self.wrapper_func(self.space, w_self, w_args, self.func) From xoraxax at codespeak.net Mon Mar 29 16:39:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 16:39:03 +0200 (CEST) Subject: [pypy-svn] r73074 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329143903.32787282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 16:39:01 2010 New Revision: 73074 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: RPythonify error message. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 16:39:01 2010 @@ -1,3 +1,4 @@ +import os import sys from pypy.rpython.lltypesystem import rffi, lltype @@ -22,7 +23,7 @@ from pypy.module.cpyext.slotdefs import slotdefs -class W_GetSetPropertyEx(GetSetProperty): # XXX fix this to be rpython +class W_GetSetPropertyEx(GetSetProperty): def getter(self, space, w_self): return generic_cpy_call(space, self.getset.c_get, w_self, self.getset.c_closure) @@ -78,7 +79,7 @@ if not func: continue if wrapper_func is None and wrapper_func_kwds is None: - print >>sys.stderr, method_name, "used by the type but no wrapper function defined!" + os.write(2, method_name + " used by the type but no wrapper function defined!") continue dict_w[method_name] = PyDescr_NewWrapper(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp) From xoraxax at codespeak.net Mon Mar 29 16:39:34 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 16:39:34 +0200 (CEST) Subject: [pypy-svn] r73075 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329143934.DDCE8282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 16:39:33 2010 New Revision: 73075 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Log: Add import and use ellipsis until we have code for the cases. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Mon Mar 29 16:39:33 2010 @@ -5,6 +5,7 @@ from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall +from pypy.interpreter.error import OperationError PyCFunction = lltype.Ptr(lltype.FuncType([PyObject, PyObject], PyObject)) @@ -61,10 +62,12 @@ if flags & METH_STATIC: raise OperationError(space.w_ValueError, "method cannot be both class and static") - w_obj = PyDescr_NewClassMethod(pto, method) + #w_obj = PyDescr_NewClassMethod(pto, method) + w_obj = space.w_Ellipsis # XXX elif flags & METH_STATIC: w_func = PyCFunction_NewEx(space, method, None) - w_obj = PyStaticMethod_New(space, w_func) + w_obj = space.w_Ellipsis # XXX + #w_obj = PyStaticMethod_New(space, w_func) else: w_obj = PyDescr_NewMethod(space, pto, method) dict_w[methodname] = w_obj From xoraxax at codespeak.net Mon Mar 29 16:39:50 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 16:39:50 +0200 (CEST) Subject: [pypy-svn] r73076 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329143950.EEA94282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 16:39:49 2010 New Revision: 73076 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Log: Forgot a wrap. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Mon Mar 29 16:39:49 2010 @@ -17,7 +17,7 @@ PyTuple_GET_SIZE if not PyTuple_CheckExact(space, ob): raise OperationError(space.w_SystemError, - "PyArg_UnpackTuple() argument list is not a tuple") + space.wrap("PyArg_UnpackTuple() argument list is not a tuple")) if n == PyTuple_GET_SIZE(space, ob): return raise operationerrfmt(space.w_TypeError, From arigo at codespeak.net Mon Mar 29 16:44:54 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 16:44:54 +0200 (CEST) Subject: [pypy-svn] r73077 - in pypy/branch/stackovf/pypy: objspace/flow rlib rlib/test Message-ID: <20100329144454.618DB282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 16:44:52 2010 New Revision: 73077 Added: pypy/branch/stackovf/pypy/rlib/rstackovf.py (contents, props changed) pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py (contents, props changed) Modified: pypy/branch/stackovf/pypy/objspace/flow/objspace.py Log: Add rstackovf.StackOverflow. Translating it is in-progress. Modified: pypy/branch/stackovf/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/stackovf/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/stackovf/pypy/objspace/flow/objspace.py Mon Mar 29 16:44:52 2010 @@ -8,6 +8,7 @@ from pypy.objspace.flow import flowcontext from pypy.objspace.flow.operation import FunctionByName from pypy.rlib.unroll import unrolling_iterable, _unroller +from pypy.rlib import rstackovf debug = 0 @@ -201,9 +202,13 @@ if not isinstance(check_class, tuple): # the simple case return ObjSpace.exception_match(self, w_exc_type, w_check_class) + # special case for StackOverflow (see rlib/rstackovf.py) + if check_class == rstackovf.StackOverflow: + w_real_class = self.wrap(rstackovf._StackOverflow) + return ObjSpace.exception_match(self, w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): - if ObjSpace.exception_match(self, w_exc_type, w_klass): + if self.exception_match(w_exc_type, w_klass): return True return False Added: pypy/branch/stackovf/pypy/rlib/rstackovf.py ============================================================================== --- (empty file) +++ pypy/branch/stackovf/pypy/rlib/rstackovf.py Mon Mar 29 16:44:52 2010 @@ -0,0 +1,15 @@ + +# RPython raises StackOverflow instead of just RuntimeError when running +# out of C stack. We need some hacks to support "except StackOverflow:" +# in untranslated code too. This StackOverflow has a strange shape in +# order to be special-cased by the flow object space (it is replaced by +# the class StackOverflow). + +class StackOverflow(RuntimeError): + """Out of C stack.""" + +# rename the variable, but the name of the class is still StackOverflow +_StackOverflow = StackOverflow + +# replace StackOverflow with this, which works in untranslated code too +StackOverflow = ((RuntimeError, RuntimeError),) Added: pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py ============================================================================== --- (empty file) +++ pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py Mon Mar 29 16:44:52 2010 @@ -0,0 +1,24 @@ +import sys +from pypy.rlib import rstackovf + +def recurse(n): + if n > 0: + return recurse(n-1) + n + return 0 + +def f(n): + try: + recurse(n) + except rstackovf.StackOverflow: + return 1 + else: + return 0 + + +def test_direct(): + assert f(sys.maxint) == 1 + +def test_llinterp(): + from pypy.rpython.test.test_llinterp import interpret + res = interpret(f, [sys.maxint]) + assert res == 1 From afa at codespeak.net Mon Mar 29 16:59:53 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 29 Mar 2010 16:59:53 +0200 (CEST) Subject: [pypy-svn] r73078 - pypy/branch/cpython-extension/pypy/translator Message-ID: <20100329145953.9616C282BD6@codespeak.net> Author: afa Date: Mon Mar 29 16:59:52 2010 New Revision: 73078 Modified: pypy/branch/cpython-extension/pypy/translator/driver.py Log: Fix translation when cpyext is not included Modified: pypy/branch/cpython-extension/pypy/translator/driver.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/driver.py (original) +++ pypy/branch/cpython-extension/pypy/translator/driver.py Mon Mar 29 16:59:52 2010 @@ -212,13 +212,16 @@ self.translator = translator self.libdef = None self.secondary_entrypoints = [] - for key in self.config.translation.secondaryentrypoints.split(","): - try: - points = secondary_entrypoints[key] - except KeyError: - raise KeyError("Entrypoints not found. I only know the keys %r." % + + if self.config.translation.secondaryentrypoints: + for key in self.config.translation.secondaryentrypoints.split(","): + try: + points = secondary_entrypoints[key] + except KeyError: + raise KeyError( + "Entrypoints not found. I only know the keys %r." % (", ".join(secondary_entrypoints.keys()), )) - self.secondary_entrypoints.extend(points) + self.secondary_entrypoints.extend(points) self.translator.driver_instrument_result = self.instrument_result From arigo at codespeak.net Mon Mar 29 17:01:04 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 17:01:04 +0200 (CEST) Subject: [pypy-svn] r73079 - in pypy/branch/stackovf/pypy: rlib/test rpython Message-ID: <20100329150104.7658A282BD6@codespeak.net> Author: arigo Date: Mon Mar 29 17:01:02 2010 New Revision: 73079 Modified: pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py pypy/branch/stackovf/pypy/rpython/exceptiondata.py pypy/branch/stackovf/pypy/rpython/llinterp.py Log: Get the StackOverflow exception "right" in the llinterp. Modified: pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py ============================================================================== --- pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py (original) +++ pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py Mon Mar 29 17:01:02 2010 @@ -22,3 +22,8 @@ from pypy.rpython.test.test_llinterp import interpret res = interpret(f, [sys.maxint]) assert res == 1 + +def test_oointerp(): + from pypy.rpython.test.test_llinterp import interpret + res = interpret(f, [sys.maxint], type_system='ootype') + assert res == 1 Modified: pypy/branch/stackovf/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/branch/stackovf/pypy/rpython/exceptiondata.py (original) +++ pypy/branch/stackovf/pypy/rpython/exceptiondata.py Mon Mar 29 17:01:02 2010 @@ -1,5 +1,6 @@ from pypy.rpython import rclass from pypy.annotation import model as annmodel +from pypy.rlib import rstackovf # the exceptions that can be implicitely raised by some operations @@ -19,6 +20,7 @@ UnicodeDecodeError: True, UnicodeEncodeError: True, NotImplementedError: True, + rstackovf._StackOverflow: True, } Modified: pypy/branch/stackovf/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stackovf/pypy/rpython/llinterp.py (original) +++ pypy/branch/stackovf/pypy/rpython/llinterp.py Mon Mar 29 17:01:02 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic +from pypy.rlib import rstackovf import sys, os import math @@ -321,6 +322,19 @@ except LLException, e: if not (catch_exception and op is block.operations[-1]): raise + except RuntimeError, e: + if 'recursion' not in str(e): # hack + raise + # xxx fish fish fish for proper etype and evalue to use + rtyper = self.llinterpreter.typer + bk = rtyper.annotator.bookkeeper + classdef = bk.getuniqueclassdef(rstackovf._StackOverflow) + exdata = rtyper.getexceptiondata() + evalue = exdata.get_standard_ll_exc_instance(rtyper, classdef) + etype = exdata.fn_type_of_exc_inst(evalue) + e = LLException(etype, evalue) + if not (catch_exception and op is block.operations[-1]): + raise e # determine nextblock and/or return value if len(block.exits) == 0: From cfbolz at codespeak.net Mon Mar 29 17:02:32 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 17:02:32 +0200 (CEST) Subject: [pypy-svn] r73080 - pypy/branch/reduce-instance-size-experiments/pypy/objspace/std Message-ID: <20100329150232.68C15282BD6@codespeak.net> Author: cfbolz Date: Mon Mar 29 17:02:30 2010 New Revision: 73080 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Log: fix translation Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 17:02:30 2010 @@ -54,6 +54,8 @@ if not space.config.objspace.std.withsharingtaggingdict: return w_value from pypy.rlib.rerased import erase + if w_value is None: + return erase(w_value) if space.is_true(space.isinstance(w_value, space.w_int)): try: return erase(space.int_w(w_value)) @@ -115,7 +117,7 @@ return new_structure = self.structure.get_next_structure(key) if new_structure.length > len(self.entries): - new_entries = [None] * new_structure.size_estimate() + new_entries = [erase(self.space, None)] * new_structure.size_estimate() for i in range(len(self.entries)): new_entries[i] = self.entries[i] self.entries = new_entries From xoraxax at codespeak.net Mon Mar 29 17:03:48 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 17:03:48 +0200 (CEST) Subject: [pypy-svn] r73081 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329150348.74623282BD6@codespeak.net> Author: xoraxax Date: Mon Mar 29 17:03:46 2010 New Revision: 73081 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Log: Add missing wraps. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Mon Mar 29 17:03:46 2010 @@ -53,7 +53,7 @@ if pto is None: if flags & METH_CLASS or flags & METH_STATIC: raise OperationError(space.w_ValueError, - "module functions cannot set METH_CLASS or METH_STATIC") + space.wrap("module functions cannot set METH_CLASS or METH_STATIC")) w_obj = PyCFunction_NewEx(space, method, w_self) else: if methodname in dict_w and not (flags & METH_COEXIST): @@ -61,7 +61,7 @@ if flags & METH_CLASS: if flags & METH_STATIC: raise OperationError(space.w_ValueError, - "method cannot be both class and static") + space.wrap("method cannot be both class and static")) #w_obj = PyDescr_NewClassMethod(pto, method) w_obj = space.w_Ellipsis # XXX elif flags & METH_STATIC: From xoraxax at codespeak.net Mon Mar 29 17:04:27 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 17:04:27 +0200 (CEST) Subject: [pypy-svn] r73082 - in pypy/branch/cpython-extension/pypy: module/cpyext rlib Message-ID: <20100329150427.DB322282BD6@codespeak.net> Author: xoraxax Date: Mon Mar 29 17:04:26 2010 New Revision: 73082 Added: pypy/branch/cpython-extension/pypy/rlib/string.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Add split function and use it in typeobject.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 17:04:26 2010 @@ -21,6 +21,7 @@ from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \ PyGetSetDef from pypy.module.cpyext.slotdefs import slotdefs +from pypy.rlib.string import split class W_GetSetPropertyEx(GetSetProperty): @@ -97,7 +98,7 @@ # XXX missing: convert_member_defs full_name = rffi.charp2str(pto.c_tp_name) - module_name, extension_name = full_name.split(".", 1) + module_name, extension_name = split(full_name, ".", 1) dict_w["__module__"] = space.wrap(module_name) W_TypeObject.__init__(self, space, extension_name, Added: pypy/branch/cpython-extension/pypy/rlib/string.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/rlib/string.py Mon Mar 29 17:04:26 2010 @@ -0,0 +1,17 @@ +def split(value, by, maxsplit): + bylen = len(by) + if bylen == 0: + raise ValueError("empty separator") + + res = [] + start = 0 + while maxsplit != 0: + next = value.find(by, start) + if next < 0: + break + res.append(value[start:next]) + start = next + bylen + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + res.append(value[start:len(value)]) + return res From xoraxax at codespeak.net Mon Mar 29 17:05:04 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 17:05:04 +0200 (CEST) Subject: [pypy-svn] r73083 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329150504.1AC31282BD6@codespeak.net> Author: xoraxax Date: Mon Mar 29 17:05:02 2010 New Revision: 73083 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: (afa, xoraxax) RPythonify generic_cpy_call. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 17:05:02 2010 @@ -331,6 +331,7 @@ def from_ref(space, ref): + assert lltype.typeOf(ref) == PyObject if not ref: return None state = space.fromcache(State) @@ -386,7 +387,6 @@ names, [name.startswith("w_") for name in names]))) def wrapper(*args): boxed_args = () - # XXX use unrolling_iterable here if DEBUG_WRAPPER: print >>sys.stderr, callable, for i, (typ, argname, is_wrapped) in argtypes_enum_ui: @@ -609,28 +609,36 @@ initfunc.call(lltype.Void) state.check_and_raise_exception() -def make_generic_cpy_call_func(decref_args): - @specialize.memo() - def get_args_count(functype): - return unrolling_iterable(range(len(functype.ARGS))) + at specialize.ll() +def generic_cpy_call(space, func, *args): + FT = lltype.typeOf(func).TO + return make_generic_cpy_call(FT, True)(space, func, *args) + + at specialize.ll() +def generic_cpy_call_dont_decref(space, func, *args): + FT = lltype.typeOf(func).TO + return make_generic_cpy_call(FT, False)(space, func, *args) + + at specialize.memo() +def make_generic_cpy_call(FT, decref_args): + unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS)) + RESULT_TYPE = FT.RESULT - @specialize.argtype(2) + @specialize.ll() def generic_cpy_call(space, func, *args): from pypy.module.cpyext.macros import Py_DECREF from pypy.module.cpyext.pyerrors import PyErr_Occurred boxed_args = () - args_count_ui = get_args_count(lltype.typeOf(func).TO) - for i in args_count_ui: # this gives a warning + for i, _ in unrolling_arg_types: arg = args[i] - if not rffi._isllptr(arg) and (isinstance(arg, W_Root) or arg is None): + if not rffi._isllptr(arg) and (arg is None or isinstance(arg, W_Root)): boxed_args += (make_ref(space, arg), ) else: boxed_args += (arg, ) result = func(*boxed_args) try: - FT = lltype.typeOf(func).TO - if FT.RESULT is PyObject: + if RESULT_TYPE is PyObject: ret = from_ref(space, result) if result: # The object reference returned from a C function @@ -655,15 +663,13 @@ return ret finally: if decref_args: - i = 0 - while i < len(args): + for i, _ in unrolling_arg_types: arg = args[i] ref = boxed_args[i] if isinstance(arg, W_Root) and ref: Py_DECREF(space, ref) - i += 1 return generic_cpy_call -generic_cpy_call = make_generic_cpy_call_func(True) -generic_cpy_call_dont_decref = make_generic_cpy_call_func(False) +generic_cpy_call = generic_cpy_call +generic_cpy_call_dont_decref = generic_cpy_call_dont_decref From arigo at codespeak.net Mon Mar 29 17:13:21 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 17:13:21 +0200 (CEST) Subject: [pypy-svn] r73084 - in pypy/branch/stackovf/pypy: rlib/test translator translator/c Message-ID: <20100329151321.9D33B282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 17:13:19 2010 New Revision: 73084 Modified: pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py pypy/branch/stackovf/pypy/translator/c/node.py pypy/branch/stackovf/pypy/translator/exceptiontransform.py Log: Minimal changes to make the new test pass. Needs reviewing. Modified: pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py ============================================================================== --- pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py (original) +++ pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py Mon Mar 29 17:13:19 2010 @@ -27,3 +27,9 @@ from pypy.rpython.test.test_llinterp import interpret res = interpret(f, [sys.maxint], type_system='ootype') assert res == 1 + +def test_c_translation(): + from pypy.translator.c.test.test_genc import compile + fn = compile(f, [int]) + res = fn(sys.maxint) + assert res == 1 Modified: pypy/branch/stackovf/pypy/translator/c/node.py ============================================================================== --- pypy/branch/stackovf/pypy/translator/c/node.py (original) +++ pypy/branch/stackovf/pypy/translator/c/node.py Mon Mar 29 17:13:19 2010 @@ -11,6 +11,7 @@ from pypy.translator.c.support import c_char_array_constant, barebonearray from pypy.translator.c.primitive import PrimitiveType, name_signed from pypy.rlib.rarithmetic import isinf, isnan +from pypy.rlib.rstackovf import _StackOverflow from pypy.translator.c import extfunc from pypy.translator.tool.cbuild import ExternalCompilationInfo from py.builtin import BaseException @@ -981,6 +982,8 @@ return 'PyExc_' + value.__name__ if value is py.code._AssertionError: return 'PyExc_AssertionError' + if value is _StackOverflow: + return 'PyExc_RuntimeError' raise Exception("don't know how to simply render py object: %r" % (value, )) Modified: pypy/branch/stackovf/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/stackovf/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/stackovf/pypy/translator/exceptiontransform.py Mon Mar 29 17:13:19 2010 @@ -13,6 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib.debug import ll_assert +from pypy.rlib.rstackovf import _StackOverflow from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.tool.sourcetools import func_with_new_name @@ -60,8 +61,8 @@ exc_data, null_type, null_value = self.setup_excdata() rclass = translator.rtyper.type_system.rclass - (runtime_error_ll_exc_type, - runtime_error_ll_exc) = self.get_builtin_exception(RuntimeError) + (stackovf_ll_exc_type, + stackovf_ll_exc) = self.get_builtin_exception(_StackOverflow) (assertion_error_ll_exc_type, assertion_error_ll_exc) = self.get_builtin_exception(AssertionError) (n_i_error_ll_exc_type, @@ -114,8 +115,8 @@ exc_data.exc_type = rclass.ll_inst_type(evalue) exc_data.exc_value = evalue - def rpyexc_raise_runtime_error(): - rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) + def rpyexc_raise_stack_overflow(): + rpyexc_raise(stackovf_ll_exc_type, stackovf_ll_exc) self.rpyexc_occured_ptr = self.build_func( "RPyExceptionOccurred", @@ -151,9 +152,9 @@ lltype.Void, jitcallkind='rpyexc_raise') # for the JIT - self.rpyexc_raise_runtime_error_ptr = self.build_func( - "RPyRaiseRuntimeError", - self.noinline(rpyexc_raise_runtime_error), + self.rpyexc_raise_stack_overflow_ptr = self.build_func( + "RPyRaiseStackOverflow", + self.noinline(rpyexc_raise_stack_overflow), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -237,10 +238,10 @@ if block.operations[i].opname == 'stack_unwind': # if there are stack_unwind ops left, # the graph was not stackless-transformed - # so we need to raise a RuntimeError in any + # so we need to raise a StackOverflow in any # case block.operations[i].opname = "direct_call" - block.operations[i].args = [self.rpyexc_raise_runtime_error_ptr] + block.operations[i].args = [self.rpyexc_raise_stack_overflow_ptr] def replace_fetch_restore_operations(self, block): # the gctransformer will create these operations. It looks as if the From xoraxax at codespeak.net Mon Mar 29 17:20:05 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 17:20:05 +0200 (CEST) Subject: [pypy-svn] r73085 - in pypy/branch/cpython-extension/pypy: module/cpyext rlib Message-ID: <20100329152005.D44B8282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 17:20:02 2010 New Revision: 73085 Removed: pypy/branch/cpython-extension/pypy/rlib/string.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py pypy/branch/cpython-extension/pypy/rlib/rstring.py Log: Use rstring and move code. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 17:20:02 2010 @@ -21,7 +21,7 @@ from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \ PyGetSetDef from pypy.module.cpyext.slotdefs import slotdefs -from pypy.rlib.string import split +from pypy.rlib.rstring import rsplit class W_GetSetPropertyEx(GetSetProperty): @@ -98,7 +98,7 @@ # XXX missing: convert_member_defs full_name = rffi.charp2str(pto.c_tp_name) - module_name, extension_name = split(full_name, ".", 1) + module_name, extension_name = rsplit(full_name, ".", 1) dict_w["__module__"] = space.wrap(module_name) W_TypeObject.__init__(self, space, extension_name, Modified: pypy/branch/cpython-extension/pypy/rlib/rstring.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rstring.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rstring.py Mon Mar 29 17:20:02 2010 @@ -1,11 +1,49 @@ - -""" String builder interface +""" String builder interface and string functions """ from pypy.rpython.extregistry import ExtRegistryEntry from pypy.annotation.model import SomeObject, SomeString, s_None,\ SomeChar, SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString + +# -------------- public API for string functions ----------------------- +def split(value, by, maxsplit=-1): + bylen = len(by) + if bylen == 0: + raise ValueError("empty separator") + + res = [] + start = 0 + while maxsplit != 0: + next = value.find(by, start) + if next < 0: + break + res.append(value[start:next]) + start = next + bylen + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + res.append(value[start:len(value)]) + return res + +def rsplit(value, by, maxsplit=-1): + res = [] + end = len(value) + bylen = len(by) + if bylen == 0: + raise ValueError("empty separator") + + while maxsplit != 0: + next = value.rfind(by, 0, end) + if next < 0: + break + res.append(value[next+bylen:end]) + end = next + maxsplit -= 1 # NB. if it's already < 0, it stays < 0 + + res.append(value[:end]) + res.reverse() + return res + # -------------- public API --------------------------------- INIT_SIZE = 100 # XXX tweak From xoraxax at codespeak.net Mon Mar 29 17:28:42 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 17:28:42 +0200 (CEST) Subject: [pypy-svn] r73086 - pypy/branch/cpython-extension/pypy/rlib/test Message-ID: <20100329152842.D2C67282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 17:28:30 2010 New Revision: 73086 Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rstring.py Log: Add tests for split/rsplit. Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rstring.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rstring.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rstring.py Mon Mar 29 17:28:30 2010 @@ -1,5 +1,26 @@ -from pypy.rlib.rstring import StringBuilder, UnicodeBuilder +from pypy.rlib.rstring import StringBuilder, UnicodeBuilder, split, rsplit + +def test_split(): + assert split("", 'x') == [''] + assert split("a", "a", 1) == ['', ''] + assert split(" ", " ", 1) == ['', ''] + assert split("aa", "a", 2) == ['', '', ''] + assert split('a|b|c|d', '|') == ['a', 'b', 'c', 'd'] + assert split('a|b|c|d', '|', 2) == ['a', 'b', 'c|d'] + assert split('a//b//c//d', '//') == ['a', 'b', 'c', 'd'] + assert split('endcase test', 'test') == ['endcase ', ''] + raises(ValueError, split, 'abc', '') + +def test_rsplit(): + assert rsplit("a", "a", 1) == ['', ''] + assert rsplit(" ", " ", 1) == ['', ''] + assert rsplit("aa", "a", 2) == ['', '', ''] + assert rsplit('a|b|c|d', '|') == ['a', 'b', 'c', 'd'] + assert rsplit('a|b|c|d', '|', 2) == ['a|b', 'c', 'd'] + assert rsplit('a//b//c//d', '//') == ['a', 'b', 'c', 'd'] + assert rsplit('endcase test', 'test') == ['endcase ', ''] + raises(ValueError, rsplit, "abc", '') def test_string_builder(): s = StringBuilder() From arigo at codespeak.net Mon Mar 29 17:33:41 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 17:33:41 +0200 (CEST) Subject: [pypy-svn] r73087 - in pypy/branch/stackovf/pypy: interpreter interpreter/test rlib rpython Message-ID: <20100329153341.CFB2D282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 17:33:33 2010 New Revision: 73087 Modified: pypy/branch/stackovf/pypy/interpreter/gateway.py pypy/branch/stackovf/pypy/interpreter/pyopcode.py pypy/branch/stackovf/pypy/interpreter/test/test_interpreter.py pypy/branch/stackovf/pypy/rlib/rstackovf.py pypy/branch/stackovf/pypy/rpython/llinterp.py Log: Use StackOverflow in the PyPy interpreter. Reduce the multiple duplication of exception-catching code in gateway.py by factoring it in a helper (and too bad if it's marginally slower). Modified: pypy/branch/stackovf/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/stackovf/pypy/interpreter/gateway.py (original) +++ pypy/branch/stackovf/pypy/interpreter/gateway.py Mon Mar 29 17:33:33 2010 @@ -22,6 +22,7 @@ from pypy.interpreter.argument import Arguments, Signature from pypy.tool.sourcetools import NiceCompile, compile2 from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.rlib import rstackovf # internal non-translatable parts: import py @@ -548,27 +549,32 @@ func.defs_w, self.minargs) try: w_result = activation._run(space, scope_w) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, - space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: if w_obj is not None: args = args.prepend(w_obj) return scope_w[0].descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result + def handle_exception(self, e): + try: + raise e + except KeyboardInterrupt: + raise OperationError(space.w_KeyboardInterrupt, + space.w_None) + except MemoryError: + raise OperationError(space.w_MemoryError, space.w_None) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow(e) + raise OperationError(space.w_RuntimeError, + space.wrap("maximum recursion depth exceeded")) + # (verbose) performance hack below class BuiltinCodePassThroughArguments0(BuiltinCode): @@ -578,20 +584,13 @@ space = func.space try: w_result = self.func__args__(space, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -604,20 +603,13 @@ space = func.space try: w_result = self.func__args__(space, w_obj, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args.prepend(w_obj)) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -629,15 +621,11 @@ def fastcall_0(self, space, w_func): try: w_result = self.fastfunc_0(space) - except KeyboardInterrupt: - 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))) + except DescrMismatch: + raise OperationError(space.w_SystemError, + space.wrap("unexpected DescrMismatch error")) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -649,20 +637,13 @@ def fastcall_1(self, space, w_func, w1): try: w_result = self.fastfunc_1(space, w1) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1])) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -674,20 +655,13 @@ def fastcall_2(self, space, w_func, w1, w2): try: w_result = self.fastfunc_2(space, w1, w2) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2])) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -699,20 +673,13 @@ def fastcall_3(self, space, func, w1, w2, w3): try: w_result = self.fastfunc_3(space, w1, w2, w3) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3])) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result @@ -724,21 +691,14 @@ def fastcall_4(self, space, func, w1, w2, w3, w4): try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3, w4])) + except Exception, e: + raise self.handle_exception(e) if w_result is None: w_result = space.w_None return w_result Modified: pypy/branch/stackovf/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/stackovf/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/stackovf/pypy/interpreter/pyopcode.py Mon Mar 29 17:33:33 2010 @@ -18,6 +18,7 @@ from pypy.tool.stdlib_opcode import unrolling_opcode_descs from pypy.tool.stdlib_opcode import opcode_method_names from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib import rstackovf def unaryoperation(operationname): """NOT_RPYTHON""" @@ -106,20 +107,13 @@ 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 - # in translated PyPy - msg = "internal error (stack overflow?)" - else: - msg = str(e) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow(e) next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, - self.space.wrap(msg)) + self.space.wrap("maximum recursion depth exceeded")) return next_instr - + def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them # into OperationErrors Modified: pypy/branch/stackovf/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/stackovf/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/stackovf/pypy/interpreter/test/test_interpreter.py Mon Mar 29 17:33:33 2010 @@ -263,3 +263,12 @@ def test_identity(self): def f(x): return x assert f(666) == 666 + + def test_raise_recursion(self): + def f(): f() + try: + f() + except RuntimeError, e: + assert str(e) == "maximum recursion depth exceeded" + else: + assert 0, "should have raised!" Modified: pypy/branch/stackovf/pypy/rlib/rstackovf.py ============================================================================== --- pypy/branch/stackovf/pypy/rlib/rstackovf.py (original) +++ pypy/branch/stackovf/pypy/rlib/rstackovf.py Mon Mar 29 17:33:33 2010 @@ -1,3 +1,4 @@ +from pypy.rlib.objectmodel import we_are_translated # RPython raises StackOverflow instead of just RuntimeError when running # out of C stack. We need some hacks to support "except StackOverflow:" @@ -13,3 +14,12 @@ # replace StackOverflow with this, which works in untranslated code too StackOverflow = ((RuntimeError, RuntimeError),) + + +def check_stack_overflow(e): + if we_are_translated(): + return + # before translation, an "except StackOverflow" includes all RuntimeErrors, + # including NotImplementedError. Special-case them. + if type(e) is not RuntimeError or 'recursion' not in str(e): + raise e Modified: pypy/branch/stackovf/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/stackovf/pypy/rpython/llinterp.py (original) +++ pypy/branch/stackovf/pypy/rpython/llinterp.py Mon Mar 29 17:33:33 2010 @@ -323,8 +323,7 @@ if not (catch_exception and op is block.operations[-1]): raise except RuntimeError, e: - if 'recursion' not in str(e): # hack - raise + rstackovf.check_stack_overflow(e) # xxx fish fish fish for proper etype and evalue to use rtyper = self.llinterpreter.typer bk = rtyper.annotator.bookkeeper From afa at codespeak.net Mon Mar 29 17:35:24 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 29 Mar 2010 17:35:24 +0200 (CEST) Subject: [pypy-svn] r73088 - in pypy/branch/cpython-extension/pypy: interpreter module/cpyext Message-ID: <20100329153524.D9F42282B9D@codespeak.net> Author: afa Date: Mon Mar 29 17:35:22 2010 New Revision: 73088 Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: - GetSetProperty() is now RPython, provided that the 'fget' functions are constants. - Fix translation of api.PyDescr_NewGetSet() Modified: pypy/branch/cpython-extension/pypy/interpreter/typedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/typedef.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/typedef.py Mon Mar 29 17:35:22 2010 @@ -9,7 +9,7 @@ DescrMismatch from pypy.interpreter.error import OperationError, operationerrfmt from pypy.tool.sourcetools import compile2, func_with_new_name -from pypy.rlib.objectmodel import instantiate, compute_identity_hash +from pypy.rlib.objectmodel import instantiate, compute_identity_hash, specialize from pypy.rlib.jit import hint class TypeDef: @@ -301,12 +301,17 @@ # ____________________________________________________________ + at specialize.arg(1) def make_descr_typecheck_wrapper(func, extraargs=(), cls=None, use_closure=False): + if func is None: + return None + return _make_descr_typecheck_wrapper(func, extraargs, cls, use_closure) + + at specialize.memo() +def _make_descr_typecheck_wrapper(func, extraargs, cls, use_closure): # - if cls is None, the wrapped object is passed to the function # - if cls is a class, an unwrapped instance is passed # - if cls is a string, XXX unused? - if func is None: - return None if cls is None and use_closure: return func if hasattr(func, 'im_func'): @@ -361,16 +366,16 @@ raise OperationError(space.w_AttributeError, space.wrap("generic property has no __objclass__")) -def make_objclass_getter(func, cls, cache={}): - if hasattr(func, 'im_func'): +def make_objclass_getter(func, cls): + if func and hasattr(func, 'im_func'): assert not cls or cls is func.im_class cls = func.im_class + return _make_objclass_getter(cls) + + at specialize.memo() +def _make_objclass_getter(cls): if not cls: return unknown_objclass_getter, cls - try: - return cache[cls] - except KeyError: - pass miniglobals = {} if isinstance(cls, str): assert cls.startswith('<'),"pythontype typecheck should begin with <" @@ -385,13 +390,11 @@ \n""" % (typeexpr,) exec compile2(source) in miniglobals res = miniglobals['objclass_getter'], cls - cache[cls] = res return res class GetSetProperty(Wrappable): def __init__(self, fget, fset=None, fdel=None, doc=None, cls=None, use_closure=False): - "NOT_RPYTHON: initialization-time only" objclass_getter, cls = make_objclass_getter(fget, cls) fget = make_descr_typecheck_wrapper(fget, cls=cls, use_closure=use_closure) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Mon Mar 29 17:35:22 2010 @@ -25,13 +25,6 @@ class W_GetSetPropertyEx(GetSetProperty): - def getter(self, space, w_self): - return generic_cpy_call(space, self.getset.c_get, w_self, self.getset.c_closure) - - def setter(self, space, w_self, w_value): - return generic_cpy_call(space, self.getset.c_set, w_self, w_value, - self.getset.c_closure) - def __init__(self, getset): self.getset = getset self.name = rffi.charp2str(getset.c_name) @@ -39,10 +32,11 @@ if doc: doc = rffi.charp2str(getset.c_doc) if getset.c_get: - get = self.getter.im_func + get = W_PyCObject.getter if getset.c_set: - set = self.setter.im_func - GetSetProperty.__init__(self, get, set, None, doc, W_PyCObject, True) + set = W_PyCObject.setter + GetSetProperty.__init__(self, get, set, None, doc, + cls=W_PyCObject, use_closure=True) def PyDescr_NewGetSet(space, getset, pto): return space.wrap(W_GetSetPropertyEx(getset)) @@ -109,6 +103,15 @@ def __init__(self, space): self.space = space + def getter(self, space, w_self): + return generic_cpy_call( + space, self.getset.c_get, w_self, + self.getset.c_closure) + + def setter(self, space, w_self, w_value): + return generic_cpy_call( + space, self.getset.c_set, w_self, w_value, + self.getset.c_closure) @cpython_api([PyObject], lltype.Void, external=False) def subtype_dealloc(space, obj): From cfbolz at codespeak.net Mon Mar 29 17:35:48 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 17:35:48 +0200 (CEST) Subject: [pypy-svn] r73089 - in pypy/branch/reduce-instance-size-experiments/pypy/rlib: . test Message-ID: <20100329153548.5B645282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 17:35:46 2010 New Revision: 73089 Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py Log: needed support for erasing of None Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py Mon Mar 29 17:35:46 2010 @@ -49,7 +49,7 @@ _about_ = erase def compute_result_annotation(self, s_obj): - return someErased + return SomeErased() def specialize_call(self, hop): return hop.r_result.specialize_call(hop) @@ -94,7 +94,7 @@ def compute_annotation(self): from pypy.rlib import _jit_vref s_obj = self.bookkeeper.immutablevalue(self.instance._x) - return someErased + return SomeErased() # annotation and rtyping support @@ -112,8 +112,6 @@ def rtyper_makekey(self): return self.__class__, -someErased = SomeErased() - class __extend__(pairtype(SomeErased, SomeErased)): def union((serased1, serased2)): @@ -127,8 +125,9 @@ def specialize_call(self, hop): s_arg, = hop.args_s - if isinstance(s_arg, annmodel.SomeInstance): - r_generic_object = getinstancerepr(hop.rtyper, None) + r_generic_object = getinstancerepr(hop.rtyper, None) + if (isinstance(s_arg, annmodel.SomeInstance) or + (s_arg.is_constant() and s_arg.const is None)): hop.exception_cannot_occur() [v] = hop.inputargs(r_generic_object) # might generate a cast_pointer return v Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py Mon Mar 29 17:35:46 2010 @@ -117,3 +117,10 @@ assert x == 16 x = interpret(f, [sys.maxint]) assert x == -1 + +def test_none(): + def foo(): + return unerase(erase(None), X) + assert foo() is None + res = interpret(foo, []) + assert not res From benjamin at codespeak.net Mon Mar 29 17:53:00 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 17:53:00 +0200 (CEST) Subject: [pypy-svn] r73090 - pypy/branch/cleanup-objspace-init Message-ID: <20100329155300.34A59282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 17:52:42 2010 New Revision: 73090 Added: pypy/branch/cleanup-objspace-init/ - copied from r73089, pypy/trunk/ Log: a branch to tame the monster From arigo at codespeak.net Mon Mar 29 18:12:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 18:12:42 +0200 (CEST) Subject: [pypy-svn] r73091 - pypy/branch/stackovf/pypy/interpreter Message-ID: <20100329161242.7C513282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 18:12:37 2010 New Revision: 73091 Modified: pypy/branch/stackovf/pypy/interpreter/gateway.py Log: Oh, how well tested that code is. Modified: pypy/branch/stackovf/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/stackovf/pypy/interpreter/gateway.py (original) +++ pypy/branch/stackovf/pypy/interpreter/gateway.py Mon Mar 29 18:12:37 2010 @@ -557,12 +557,12 @@ self.descr_reqcls, args) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result - def handle_exception(self, e): + def handle_exception(self, space, e): try: raise e except KeyboardInterrupt: @@ -590,7 +590,7 @@ self.descr_reqcls, args) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -609,7 +609,7 @@ self.descr_reqcls, args.prepend(w_obj)) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -625,7 +625,7 @@ raise OperationError(space.w_SystemError, space.wrap("unexpected DescrMismatch error")) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -643,7 +643,7 @@ self.descr_reqcls, Arguments(space, [w1])) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -661,7 +661,7 @@ self.descr_reqcls, Arguments(space, [w1, w2])) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -679,7 +679,7 @@ self.descr_reqcls, Arguments(space, [w1, w2, w3])) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -698,7 +698,7 @@ Arguments(space, [w1, w2, w3, w4])) except Exception, e: - raise self.handle_exception(e) + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result From getxsick at codespeak.net Mon Mar 29 18:12:54 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 18:12:54 +0200 (CEST) Subject: [pypy-svn] r73092 - pypy/build/ubuntu/trunk Message-ID: <20100329161254.9CB7F282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 18:12:52 2010 New Revision: 73092 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: set environment variables. Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 18:12:52 2010 @@ -5,6 +5,10 @@ LOGFILE="autobuild.log" NEXT_RELEASE=1.3 + +export DEBFULLNAME="Bartosz Skowron" +export DEBEMAIL="getxsick at gmail.com" + #( echo "--- Start a new build at `date -R`" From getxsick at codespeak.net Mon Mar 29 18:13:42 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 18:13:42 +0200 (CEST) Subject: [pypy-svn] r73093 - pypy/build/ubuntu/trunk Message-ID: <20100329161342.C2945282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 18:13:41 2010 New Revision: 73093 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: gpg-agent verification. would be nice to fix XXX Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 18:13:41 2010 @@ -9,6 +9,21 @@ export DEBFULLNAME="Bartosz Skowron" export DEBEMAIL="getxsick at gmail.com" +if !([ -f "$HOME/.gpg-agent-info" ] && \ + kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null) +then + # XXX runing gpg-agent doesn't make more sense, cause we need + # to type the passphrase (for first signing) + # + # i have no idea how to avoid it and the only known for me way is + # to send email notification to do it manually ;) + echo "--- gpg-agent is down, send the email notification /`date -R`/" + #eval `gpg-agent --daemon > $HOME/.gpg-agent-info` + echo "`date -R` : gpg-agent is down." | mail -s "[pypy-autobuild] gpg-agent is down" $DEBEMAIL + exit 10 +fi +. "$HOME/.gpg-agent-info" + #( echo "--- Start a new build at `date -R`" From getxsick at codespeak.net Mon Mar 29 18:18:10 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 18:18:10 +0200 (CEST) Subject: [pypy-svn] r73094 - pypy/build/ubuntu/trunk Message-ID: <20100329161810.07205282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 18:18:09 2010 New Revision: 73094 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: add email notification when life is good Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 18:18:09 2010 @@ -19,7 +19,8 @@ # to send email notification to do it manually ;) echo "--- gpg-agent is down, send the email notification /`date -R`/" #eval `gpg-agent --daemon > $HOME/.gpg-agent-info` - echo "`date -R` : gpg-agent is down." | mail -s "[pypy-autobuild] gpg-agent is down" $DEBEMAIL + echo "`date -R` : gpg-agent is down." | \ + mail -s "[pypy-autobuild] gpg-agent is down" $DEBEMAIL exit 10 fi . "$HOME/.gpg-agent-info" @@ -62,5 +63,7 @@ done rm changelog.old rm -rf pypy* +echo "`date -R` : Packages built and sent successfully." | \ +mail -s "[pypy-autobuild] status" $DEBEMAIL echo "--- Finish the new build at `date -R`" #) &>>$LOGFILE From getxsick at codespeak.net Mon Mar 29 18:18:47 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 18:18:47 +0200 (CEST) Subject: [pypy-svn] r73095 - pypy/build/ubuntu/trunk Message-ID: <20100329161847.81C44282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 18:18:46 2010 New Revision: 73095 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: enable dput command Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 18:18:46 2010 @@ -58,7 +58,7 @@ cd .. echo " -- Upload a package" - #dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${dist}1_source.changes + dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${dist}1_source.changes done rm changelog.old From getxsick at codespeak.net Mon Mar 29 18:20:38 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 18:20:38 +0200 (CEST) Subject: [pypy-svn] r73096 - pypy/build/ubuntu/trunk Message-ID: <20100329162038.0EFAF282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 18:20:36 2010 New Revision: 73096 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: enable logging Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 18:20:36 2010 @@ -9,6 +9,8 @@ export DEBFULLNAME="Bartosz Skowron" export DEBEMAIL="getxsick at gmail.com" +( + if !([ -f "$HOME/.gpg-agent-info" ] && \ kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null) then @@ -25,7 +27,6 @@ fi . "$HOME/.gpg-agent-info" -#( echo "--- Start a new build at `date -R`" echo " -- Check out pypy trunk" @@ -66,4 +67,4 @@ echo "`date -R` : Packages built and sent successfully." | \ mail -s "[pypy-autobuild] status" $DEBEMAIL echo "--- Finish the new build at `date -R`" -#) &>>$LOGFILE +) &>>$LOGFILE From afa at codespeak.net Mon Mar 29 18:22:48 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 29 Mar 2010 18:22:48 +0200 (CEST) Subject: [pypy-svn] r73097 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329162248.BB192282B9D@codespeak.net> Author: afa Date: Mon Mar 29 18:22:46 2010 New Revision: 73097 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Log: add the space when calling W_PyCFunctionObject.call() This does not change anything of course, but it feels more correct to me. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Mon Mar 29 18:22:46 2010 @@ -16,12 +16,10 @@ class W_PyCFunctionObject(Wrappable): def __init__(self, space, ml, w_self): - self.space = space self.ml = ml self.w_self = w_self - def call(self, w_self, args_tuple): - space = self.space + def call(self, space, w_self, args_tuple): # Call the C function if w_self is None: w_self = self.w_self @@ -56,15 +54,16 @@ pyo = rffi.cast(PyObject, pto) self.w_objclass = from_ref(space, pyo) - def call(self, w_self, w_args, w_kw): + def call(self, space, w_self, w_args, w_kw): if self.wrapper_func is None: assert self.wrapper_func_kwds is not None - return self.wrapper_func_kwds(self.space, w_self, w_args, self.func, w_kw) - if self.space.is_true(w_kw): - raise operationerrfmt(self.space.w_TypeError, - "wrapper %s doesn't take any keyword arguments", - self.method_name) - return self.wrapper_func(self.space, w_self, w_args, self.func) + return self.wrapper_func_kwds(space, w_self, w_args, self.func, w_kw) + if space.is_true(w_kw): + raise operationerrfmt( + space.w_TypeError, + "wrapper %s doesn't take any keyword arguments", + self.method_name) + return self.wrapper_func(space, w_self, w_args, self.func) def descr_method_repr(self): return self.space.wrap("" % (self.method_name, @@ -79,7 +78,7 @@ w_kw = space.newdict() for key, w_obj in kw_w.items(): space.setitem(w_kw, space.wrap(key), w_obj) - return self.call(w_self, w_args, w_kw) + return self.call(space, w_self, w_args, w_kw) @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -90,7 +89,7 @@ if kw_w: raise OperationError(space.w_TypeError, space.wrap("keywords not yet supported")) - ret = self.call(None, w_args) + ret = self.call(space, None, w_args) return ret @unwrap_spec(ObjSpace, W_Root, Arguments) @@ -102,7 +101,7 @@ if kw_w: raise OperationError(space.w_TypeError, space.wrap("keywords not yet supported")) - ret = self.call(w_instance, w_args) + ret = self.call(space, w_instance, w_args) return ret def cmethod_descr_get(space, w_function, w_obj, w_cls=None): From cfbolz at codespeak.net Mon Mar 29 18:23:45 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 18:23:45 +0200 (CEST) Subject: [pypy-svn] r73098 - in pypy/branch/reduce-instance-size-experiments/pypy/objspace/std: . test Message-ID: <20100329162345.2310C282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 18:23:44 2010 New Revision: 73098 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py Log: refactor to have a new "AttributeShape" object. will add new functionality to that object soon. Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 18:23:44 2010 @@ -10,9 +10,10 @@ _immutable_fields_ = ["keys", "length", "back_struct", "other_structs", "last_key"] - def __init__(self, keys=None, length=0, + def __init__(self, space, keys=None, length=0, last_key=None, back_struct=None): + self.space = space if keys is None: keys = {} self.keys = keys @@ -27,15 +28,15 @@ def new_structure(self, added_key): keys = self.keys.copy() - keys[added_key] = len(self.keys) - new_structure = SharedStructure(keys, self.length + 1, + keys[added_key] = AttributeShape(self.space, len(self.keys)) + new_structure = SharedStructure(self.space, keys, self.length + 1, added_key, self) self.other_structs.set(added_key, new_structure) return new_structure @purefunction_promote('0') - def lookup_position(self, key): - return self.keys.get(key, -1) + def lookup_attribute(self, key): + return self.keys.get(key, None) @purefunction_promote('0') def get_next_structure(self, key): @@ -50,6 +51,51 @@ def size_estimate(self): return self._size_estimate >> NUM_DIGITS + def convert_to(self, new_structure, entries): + if new_structure.length > len(entries): + new_entries = [erase(self.space, None)] * new_structure.size_estimate() + for i in range(len(entries)): + new_entries[i] = entries[i] + entries = new_entries + assert self.length + 1 == new_structure.length + return entries + + @purefunction_promote('0') + def find_structure_del_key(self, num_back): + keys = [None] * num_back + for i in range(num_back): + keys[i] = self.last_key + self = self.back_struct + # go back the structure that contains the deleted key + self = self.back_struct + for i in range(num_back - 1, -1, -1): + self = self.get_next_structure(keys[i]) + return self + + +class AttributeShape(object): + _immutable_ = True + def __init__(self, space, index): + self.space = space + self.index = index + + def getfield(self, fields): + return unerase(self.space, fields[self.index]) + def setfield(self, fields, val): + fields[self.index] = erase(self.space, val) + def delfield(self, fields, structure): + struct_len = structure.length + num_back = struct_len - self.index - 1 + if num_back > 0: + for i in range(self.index, struct_len - 1): + fields[i] = fields[i + 1] + # don't make the entries list shorter, new keys might be added soon + fields[struct_len - 1] = erase(self.space, None) + return structure.find_structure_del_key(num_back) + + + + def erase(space, w_value): if not space.config.objspace.std.withsharingtaggingdict: return w_value @@ -74,7 +120,7 @@ class State(object): def __init__(self, space): - self.empty_structure = SharedStructure() + self.empty_structure = SharedStructure(space) self.emptylist = [] @@ -96,10 +142,10 @@ return self._as_rdict().getitem(w_lookup) def impl_getitem_str(self, lookup): - i = self.structure.lookup_position(lookup) - if i == -1: + attr = self.structure.lookup_attribute(lookup) + if attr is None: return None - return unerase(self.space, self.entries[i]) + return attr.getfield(self.entries) def impl_setitem(self, w_key, w_value): space = self.space @@ -110,20 +156,14 @@ @unroll_safe def impl_setitem_str(self, key, w_value, shadows_type=True): - e_value = erase(self.space, w_value) - i = self.structure.lookup_position(key) - if i != -1: - self.entries[i] = e_value + attr = self.structure.lookup_attribute(key) + if attr is not None: + attr.setfield(self.space, w_value) return new_structure = self.structure.get_next_structure(key) - if new_structure.length > len(self.entries): - new_entries = [erase(self.space, None)] * new_structure.size_estimate() - for i in range(len(self.entries)): - new_entries[i] = self.entries[i] - self.entries = new_entries - - self.entries[new_structure.length - 1] = e_value - assert self.structure.length + 1 == new_structure.length + self.entries = self.structure.convert_to(new_structure, self.entries) + attr = new_structure.lookup_attribute(key) + attr.setfield(self.entries, w_value) self.structure = new_structure def impl_delitem(self, w_key): @@ -131,27 +171,10 @@ w_key_type = space.type(w_key) if space.is_w(w_key_type, space.w_str): key = space.str_w(w_key) - pos = self.structure.lookup_position(key) - if pos == -1: + attr = self.structure.lookup_attribute(key) + if attr is None: raise KeyError - struct_len = self.structure.length - num_back = struct_len - pos - 1 - - if num_back > 0: - for i in range(pos, struct_len - 1): - self.entries[i] = self.entries[i + 1] - # don't make the entries list shorter, new keys might be added soon - self.entries[struct_len - 1] = erase(self.space, None) - structure = self.structure - keys = [None] * num_back - for i in range(num_back): - keys[i] = structure.last_key - structure = structure.back_struct - # go back the structure that contains the deleted key - structure = structure.back_struct - for i in range(num_back - 1, -1, -1): - structure = structure.get_next_structure(keys[i]) - self.structure = structure + self.structure = attr.delfield(self.entries, self.structure) elif _is_sane_hash(space, w_key_type): raise KeyError else: @@ -166,7 +189,7 @@ def impl_keys(self): space = self.space return [space.wrap(key) - for (key, item) in self.structure.keys.iteritems()] + for (key, _) in self.structure.keys.iteritems()] def impl_values(self): return [unerase(self.space, self.entries[i]) @@ -176,17 +199,17 @@ space = self.space return [space.newtuple([ space.wrap(key), - unerase(self.space, self.entries[item])]) - for (key, item) in self.structure.keys.iteritems()] + attr.getfield(self.entries)]) + for (key, attr) in self.structure.keys.iteritems()] def impl_clear(self): space = self.space self.structure = space.fromcache(State).empty_structure self.entries = space.fromcache(State).emptylist def _as_rdict(self): r_dict_content = self.initialize_as_rdict() - for k, i in self.structure.keys.items(): - r_dict_content[self.space.wrap(k)] = unerase( - self.space, self.entries[i]) + for k, attr in self.structure.keys.items(): + r_dict_content[self.space.wrap(k)] = attr.getfield( + self.entries) self._clear_fields() return self @@ -202,8 +225,8 @@ def next_entry(self): implementation = self.dictimplementation assert isinstance(implementation, SharedDictImplementation) - for key, index in self.iterator: - e_value = implementation.entries[index] - return self.space.wrap(key), unerase(self.space, e_value) + for key, attr in self.iterator: + w_value = attr.getfield(implementation.entries) + return self.space.wrap(key), w_value else: return None, None Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py Mon Mar 29 18:23:44 2010 @@ -11,7 +11,7 @@ return structure def test_size_estimate(): - empty_structure = SharedStructure() + empty_structure = SharedStructure(None) instances = [] for i in range(100): instances.append(instance_with_keys(empty_structure, "a", "b", "c", "d", "e", "f")) @@ -21,7 +21,7 @@ assert empty_structure.other_structs.get("x").size_estimate() == 2 def test_size_estimate2(): - empty_structure = SharedStructure() + empty_structure = SharedStructure(None) instances = [] for i in range(100): instances.append(instance_with_keys(empty_structure, "a", "b", "c", "d", "e", "f")) @@ -33,6 +33,8 @@ def unerase_entries(space, d): return [unerase(space, e) for e in d.entries] +def key_positions(d): + return dict([(key, attr.index) for key, attr in d.structure.keys.items()]) def test_delete(): space = FakeSpace() @@ -43,7 +45,7 @@ d.delitem("b") assert d.r_dict_content is None assert unerase_entries(space, d) == [1, 3, None] - assert d.structure.keys == {"a": 0, "c": 1} + assert key_positions(d) == {"a": 0, "c": 1} assert d.getitem("a") == 1 assert d.getitem("c") == 3 assert d.getitem("b") is None @@ -51,11 +53,11 @@ d.delitem("c") assert unerase_entries(space, d) == [1, None, None] - assert d.structure.keys == {"a": 0} + assert key_positions(d) == {"a": 0} d.delitem("a") assert unerase_entries(space, d) == [None, None, None] - assert d.structure.keys == {} + assert key_positions(d) == {} d = SharedDictImplementation(space) d.setitem_str("a", 1) @@ -69,4 +71,4 @@ d.setitem_str("i", 9) d.delitem("d") assert unerase_entries(space, d) == [1, 2, 3, 5, 6, 7, 8, 9, None] - assert d.structure.keys == {"a": 0, "b": 1, "c": 2, "e": 3, "f": 4, "g": 5, "h": 6, "i": 7} + assert key_positions(d) == {"a": 0, "b": 1, "c": 2, "e": 3, "f": 4, "g": 5, "h": 6, "i": 7} From afa at codespeak.net Mon Mar 29 18:23:59 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 29 Mar 2010 18:23:59 +0200 (CEST) Subject: [pypy-svn] r73099 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329162359.DE435282B9D@codespeak.net> Author: afa Date: Mon Mar 29 18:23:58 2010 New Revision: 73099 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Lots of translation fixes in api.py Still remaining: the make_wrapper() function Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 18:23:58 2010 @@ -131,20 +131,28 @@ % func) def make_unwrapper(catch_exception): names = api_function.argnames - types_names_enum_ui = unrolling_iterable(enumerate(zip(api_function.argtypes, - names, [name.startswith("w_") for name in names]))) - @specialize.argtype(1) + types_names_enum_ui = unrolling_iterable(enumerate( + zip(api_function.argtypes, + [name.startswith("w_") for name in names]))) + + @specialize.ll() def unwrapper(space, *args): newargs = () - to_decref = () - for i, (typ, name, is_wrapped) in types_names_enum_ui: + to_decref = [] + for i, (ARG, is_wrapped) in types_names_enum_ui: input_arg = args[i] - if typ is PyObject: - if not is_wrapped and (input_arg is None - or isinstance(input_arg, W_Root)): + if ARG is PyObject and not is_wrapped: + # build a reference + if input_arg is None: + arg = lltype.nullptr(PyObject.TO) + elif isinstance(input_arg, W_Root): arg = make_ref(space, input_arg) - to_decref += (arg, ) - elif is_wrapped and not isinstance(input_arg, W_Root): + to_decref.append(arg) + else: + arg = input_arg + elif ARG is PyObject and is_wrapped: + # convert to a wrapped object + if not isinstance(input_arg, W_Root): arg = from_ref(space, input_arg) else: arg = input_arg @@ -175,12 +183,12 @@ unwrapper._always_inline_ = True return unwrapper - unwrapper_True = make_unwrapper(True) - unwrapper_False = make_unwrapper(False) + unwrapper_catch = make_unwrapper(True) + unwrapper_raise = make_unwrapper(False) if external: FUNCTIONS[func.func_name] = api_function - INTERPLEVEL_API[func.func_name] = unwrapper_True - return unwrapper_False + INTERPLEVEL_API[func.func_name] = unwrapper_catch # used in tests + return unwrapper_raise # used in 'normal' RPython code. return decorate def cpython_api_c(): @@ -621,30 +629,41 @@ @specialize.memo() def make_generic_cpy_call(FT, decref_args): + from pypy.module.cpyext.macros import Py_DECREF + from pypy.module.cpyext.pyerrors import PyErr_Occurred unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS)) RESULT_TYPE = FT.RESULT @specialize.ll() def generic_cpy_call(space, func, *args): - from pypy.module.cpyext.macros import Py_DECREF - from pypy.module.cpyext.pyerrors import PyErr_Occurred - boxed_args = () - for i, _ in unrolling_arg_types: + to_decref = [] + for i, ARG in unrolling_arg_types: arg = args[i] - if not rffi._isllptr(arg) and (arg is None or isinstance(arg, W_Root)): - boxed_args += (make_ref(space, arg), ) + if ARG is PyObject: + if arg is None: + boxed_args += (lltype.nullptr(PyObject.TO),) + elif isinstance(arg, W_Root): + ref = make_ref(space, arg) + boxed_args += (ref,) + if decref_args: + to_decref.append(ref) + else: + boxed_args += (arg,) else: - boxed_args += (arg, ) + boxed_args += (arg,) result = func(*boxed_args) try: if RESULT_TYPE is PyObject: - ret = from_ref(space, result) - if result: - # The object reference returned from a C function - # that is called from Python must be an owned reference + if isinstance(result, W_Root): + ret = result + else: + ret = from_ref(space, result) + # The object reference returned from a C function + # that is called from Python must be an owned reference # - ownership is transferred from the function to its caller. - Py_DECREF(space, result) + if result: + Py_DECREF(space, result) # Check for exception consistency has_error = PyErr_Occurred(space) is not None @@ -663,13 +682,7 @@ return ret finally: if decref_args: - for i, _ in unrolling_arg_types: - arg = args[i] - ref = boxed_args[i] - if isinstance(arg, W_Root) and ref: - Py_DECREF(space, ref) + for ref in to_decref: + Py_DECREF(space, ref) return generic_cpy_call -generic_cpy_call = generic_cpy_call -generic_cpy_call_dont_decref = generic_cpy_call_dont_decref - From arigo at codespeak.net Mon Mar 29 18:24:42 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 18:24:42 +0200 (CEST) Subject: [pypy-svn] r73100 - pypy/branch/stackovf/pypy/translator/c/src Message-ID: <20100329162442.E4807282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 18:24:40 2010 New Revision: 73100 Modified: pypy/branch/stackovf/pypy/translator/c/src/exception.h Log: Convert StackOverflows to PyExc_RuntimeError. Modified: pypy/branch/stackovf/pypy/translator/c/src/exception.h ============================================================================== --- pypy/branch/stackovf/pypy/translator/c/src/exception.h (original) +++ pypy/branch/stackovf/pypy/translator/c/src/exception.h Mon Mar 29 18:24:40 2010 @@ -104,6 +104,9 @@ /* workaround against the py lib's BuiltinAssertionError */ pycls = PyExc_AssertionError; } + else if (strcmp(clsname, "StackOverflow") == 0) { + pycls = PyExc_RuntimeError; + } else { pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); if (pycls == NULL || !PyExceptionClass_Check(pycls) || From arigo at codespeak.net Mon Mar 29 18:32:09 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 18:32:09 +0200 (CEST) Subject: [pypy-svn] r73101 - pypy/branch/stackovf/pypy/module/_sre Message-ID: <20100329163209.92716282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 18:31:52 2010 New Revision: 73101 Modified: pypy/branch/stackovf/pypy/module/_sre/interp_sre.py Log: Catch the RuntimeErrors coming from rlib.rsre and raise w_RuntimeErrors. Modified: pypy/branch/stackovf/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/branch/stackovf/pypy/module/_sre/interp_sre.py (original) +++ pypy/branch/stackovf/pypy/module/_sre/interp_sre.py Mon Mar 29 18:31:52 2010 @@ -177,10 +177,20 @@ state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.search(pattern_codes)) + try: + res = state.search(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) def w_match(space, w_state, w_pattern_codes): state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.match(pattern_codes)) + try: + res = state.match(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) From arigo at codespeak.net Mon Mar 29 18:41:08 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 18:41:08 +0200 (CEST) Subject: [pypy-svn] r73102 - in pypy/branch/stackovf/pypy: rlib translator/stackless Message-ID: <20100329164108.58F7F282BD6@codespeak.net> Author: arigo Date: Mon Mar 29 18:40:59 2010 New Revision: 73102 Modified: pypy/branch/stackovf/pypy/rlib/rzipfile.py pypy/branch/stackovf/pypy/translator/stackless/code.py Log: Remove two "raise RuntimeErrors" in RPython. Modified: pypy/branch/stackovf/pypy/rlib/rzipfile.py ============================================================================== --- pypy/branch/stackovf/pypy/rlib/rzipfile.py (original) +++ pypy/branch/stackovf/pypy/rlib/rzipfile.py Mon Mar 29 18:40:59 2010 @@ -217,7 +217,7 @@ + fheader[_FH_EXTRA_FIELD_LENGTH]) fname = fp.read(fheader[_FH_FILENAME_LENGTH]) if fname != data.orig_filename: - raise RuntimeError, \ + raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( data.orig_filename, fname) fp.seek(self.start_dir, 0) Modified: pypy/branch/stackovf/pypy/translator/stackless/code.py ============================================================================== --- pypy/branch/stackovf/pypy/translator/stackless/code.py (original) +++ pypy/branch/stackovf/pypy/translator/stackless/code.py Mon Mar 29 18:40:59 2010 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.tool.sourcetools import func_with_new_name -from pypy.rlib import rarithmetic, objectmodel +from pypy.rlib import rarithmetic, objectmodel, rstackovf from pypy.translator.stackless import frame from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE, STORAGE_TYPES_AND_FIELDS @@ -382,7 +382,7 @@ # uncommon case: exceed the limit pending = pending.f_back pending.f_depth = depth - 1 - e = RuntimeError() + e = rstackovf._StackOverflow() if not pending: raise e global_state.exception = e From cfbolz at codespeak.net Mon Mar 29 18:41:08 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 18:41:08 +0200 (CEST) Subject: [pypy-svn] r73103 - in pypy/branch/reduce-instance-size-experiments/pypy/objspace/std: . test Message-ID: <20100329164108.27D78282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 18:41:03 2010 New Revision: 73103 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py Log: grumble grumble tests grumble grumble Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 18:41:03 2010 @@ -158,7 +158,7 @@ def impl_setitem_str(self, key, w_value, shadows_type=True): attr = self.structure.lookup_attribute(key) if attr is not None: - attr.setfield(self.space, w_value) + attr.setfield(self.entries, w_value) return new_structure = self.structure.get_next_structure(key) self.entries = self.structure.convert_to(new_structure, self.entries) Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_dictmultiobject.py Mon Mar 29 18:41:03 2010 @@ -37,6 +37,10 @@ space.setitem(d,wk1,wone) wback = space.getitem(d,wk1) assert self.space.eq_w(wback,wone) + wtwo = space.wrap(2) + space.setitem(d,wk1,wtwo) + wback = space.getitem(d,wk1) + assert self.space.eq_w(wback,wtwo) def test_delitem(self): space = self.space @@ -522,6 +526,14 @@ l[0] = 24 assert a.abc == 12 + def test_setfield_twice(self): + class A(object): + pass + a = A() + a.x = 1 + a.x = 2 + assert a.x == 2 + def test_items(self): class A(object): pass @@ -533,7 +545,7 @@ def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withsharingtaggingdict": True}) -class AppTest_DictSharing(AppTest_DictObject): +class AppTest_DictSharingTagging(AppTest_DictObject): def setup_class(cls): cls.space = gettestobjspace(**{"objspace.std.withsharingtaggingdict": True}) From benjamin at codespeak.net Mon Mar 29 18:46:16 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 18:46:16 +0200 (CEST) Subject: [pypy-svn] r73104 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329164616.7AF06282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 18:46:05 2010 New Revision: 73104 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/boolobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/complexobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictmultiobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxyobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/intobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/iterobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/listobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/noneobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objectobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/proxyobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/rangeobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeunicodeobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/setobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/sliceobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/strjoinobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/strsliceobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/typeobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodeobject.py Log: move towards removing the dependence of objects on objspace.py * move registerimplementation to model.py and use a set * remove "from pypy.objspace.std.objspace import *" Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/boolobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/boolobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.intobject import W_IntObject Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/complexobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/complexobject.py Mon Mar 29 18:46:05 2010 @@ -1,6 +1,7 @@ from pypy.interpreter import gateway -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.floatobject import W_FloatObject, _hash_float import math Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictmultiobject.py Mon Mar 29 18:46:05 2010 @@ -1,6 +1,6 @@ import py, sys -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxyobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxyobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxyobject.py Mon Mar 29 18:46:05 2010 @@ -1,11 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all def descr_get_dictproxy(space, w_obj): return W_DictProxyObject(w_obj.getdict()) class W_DictProxyObject(W_Object): from pypy.objspace.std.dictproxytype import dictproxy_typedef as typedef - + def __init__(w_self, w_dict): w_self.w_dict = w_dict Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py Mon Mar 29 18:46:05 2010 @@ -1,11 +1,15 @@ import operator, new -from pypy.objspace.std.objspace import * from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.objspace import StdObjSpace from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan from pypy.rlib.rarithmetic import formatd, LONG_BIT from pypy.rlib.rbigint import rbigint +from pypy.tool.sourcetools import func_with_new_name import math from pypy.objspace.std.intobject import W_IntObject Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/intobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/intobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/intobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/iterobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/iterobject.py Mon Mar 29 18:46:05 2010 @@ -4,7 +4,9 @@ tested, and complete. The only missing feature is support for function-iteration. """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_AbstractSeqIterObject(W_Object): Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/listobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/listobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,9 @@ import sys -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.objspace import StdObjSpace +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rbigint import rbigint, SHIFT Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py Mon Mar 29 18:46:05 2010 @@ -8,6 +8,12 @@ import pypy.interpreter.pycode import pypy.interpreter.special +_registered_implementations = set() +def registerimplementation(implcls): + """Hint to objspace.std.model to register the implementation class.""" + assert issubclass(implcls, W_Object) + _registered_implementations.add(implcls) + option_to_typename = { "withsmallint" : ["smallintobject.W_SmallIntObject"], "withstrslice" : ["strsliceobject.W_StringSliceObject"], @@ -132,8 +138,7 @@ if config.objspace.std.withrope: del self.typeorder[stringobject.W_StringObject] - #check if we missed implementations - from pypy.objspace.std.objspace import _registered_implementations + # check if we missed implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or implcls in self.imported_but_not_registered), ( @@ -146,7 +151,7 @@ # register the order in which types are converted into each others # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - + if config.objspace.std.withsmallint: self.typeorder[boolobject.W_BoolObject] += [ (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/noneobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/noneobject.py Mon Mar 29 18:46:05 2010 @@ -2,9 +2,10 @@ None Object implementation ok and tested -""" +""" -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_NoneObject(W_Object): from pypy.objspace.std.nonetype import none_typedef as typedef Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objectobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objectobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objectobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import W_Object, register_all +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all class W_ObjectObject(W_Object): Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 18:46:05 2010 @@ -20,13 +20,6 @@ import os import __builtin__ -_registered_implementations = {} -def registerimplementation(implcls): - # hint to objspace.std.model to register the implementation class - assert issubclass(implcls, W_Object) - _registered_implementations[implcls] = True - - ################################################################## class StdObjSpace(ObjSpace, DescrOperation): Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/proxyobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/proxyobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/proxyobject.py Mon Mar 29 18:46:05 2010 @@ -2,7 +2,7 @@ """ transparent list implementation """ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.proxy_helpers import register_type from pypy.interpreter.error import OperationError from pypy.interpreter import baseobjspace, argument @@ -73,7 +73,7 @@ W_Transparent.__name__ = name return W_Transparent -W_Transparent = transparent_class('W_Transparent', Wrappable) +W_Transparent = transparent_class('W_Transparent', baseobjspace.Wrappable) W_TransparentObject = transparent_class('W_TransparentObject', W_Object) from pypy.objspace.std.objecttype import object_typedef Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/rangeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/rangeobject.py Mon Mar 29 18:46:05 2010 @@ -1,12 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.inttype import wrapint 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 - -from pypy.objspace.std import slicetype +from pypy.objspace.std import listtype, iterobject, slicetype from pypy.interpreter import gateway, baseobjspace def length(start, stop, step): Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/ropeunicodeobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/setobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/setobject.py Mon Mar 29 18:46:05 2010 @@ -1,7 +1,8 @@ -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.rlib.objectmodel import r_dict from pypy.rlib.rarithmetic import intmask, r_uint +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway from pypy.interpreter.argument import Signature from pypy.objspace.std.settype import set_typedef as settypedef Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/sliceobject.py Mon Mar 29 18:46:05 2010 @@ -5,8 +5,10 @@ indices method tested, OK """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.slicetype import _Eval_SliceIndex Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py Mon Mar 29 18:46:05 2010 @@ -2,7 +2,9 @@ Implementation of small ints, stored as odd-valued pointers in the translated PyPy. To enable them, see inttype.py. """ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.objspace.std.inttype import wrapint Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/strjoinobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/strjoinobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/strjoinobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/strsliceobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.inttype import wrapint from pypy.rlib.rarithmetic import intmask from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice @@ -8,7 +10,7 @@ class W_TupleObject(W_Object): from pypy.objspace.std.tupletype import tuple_typedef as typedef _immutable_ = True - + def __init__(w_self, wrappeditems): make_sure_not_resized(wrappeditems) w_self.wrappeditems = wrappeditems # a list of wrapped values Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/typeobject.py Mon Mar 29 18:46:05 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodeobject.py Mon Mar 29 18:46:05 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt From benjamin at codespeak.net Mon Mar 29 19:12:54 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 19:12:54 +0200 (CEST) Subject: [pypy-svn] r73105 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329171254.8D4A1282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 19:12:45 2010 New Revision: 73105 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/marshal_impl.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py Log: move MM container to model.py Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py Mon Mar 29 19:12:45 2010 @@ -1,9 +1,9 @@ import operator, new from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.objspace.std import model from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.objspace import StdObjSpace from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan @@ -401,11 +401,13 @@ w_float2 = delegate_Long2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, W_NoneObject, order=1) +model.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, + W_NoneObject, order=1) def pow_neg__Int_Int_None(space, w_int1, w_int2, thirdarg): w_float1 = delegate_Int2Float(space, w_int1) w_float2 = delegate_Int2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=2) +model.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=2) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/longobject.py Mon Mar 29 19:12:45 2010 @@ -1,8 +1,8 @@ import sys from pypy.interpreter.error import OperationError +from pypy.objspace.std import model from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.objspace import StdObjSpace from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject @@ -309,7 +309,8 @@ return %(opname)s__Long_Long(space, w_long1, w_long2) """ % {'opname': opname}, '', 'exec') - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], W_IntObject, W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], + W_IntObject, W_IntObject, order=1) # unary ops for opname in ['neg', 'abs']: @@ -319,7 +320,8 @@ return %(opname)s__Long(space, w_long1) """ % {'opname': opname} - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int' % opname], W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int' % opname], + W_IntObject, order=1) # pow def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3): @@ -332,7 +334,9 @@ w_long2 = delegate_Int2Long(space, w_int2) return pow__Long_Long_Long(space, w_long1, w_long2, w_long3) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=1) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, W_LongObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, + W_LongObject, order=1) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/marshal_impl.py Mon Mar 29 19:12:45 2010 @@ -11,8 +11,8 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all from pypy.rlib.rarithmetic import LONG_BIT +from pypy.objspace.std import longobject, model from pypy.objspace.std.longobject import SHIFT as long_bits -from pypy.objspace.std.objspace import StdObjSpace from pypy.interpreter.special import Ellipsis from pypy.interpreter.pycode import PyCode from pypy.interpreter import gateway, unicodehelper @@ -32,8 +32,6 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.unicodeobject import W_UnicodeObject -import longobject - from pypy.module.marshal.interp_marshal import register TYPE_NULL = '0' @@ -125,7 +123,7 @@ def marshal_w_Ellipsis(space, w_ellipsis, m): m.atom(TYPE_ELLIPSIS) -StdObjSpace.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) +model.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) def unmarshal_Ellipsis(space, u, tc): return space.w_Ellipsis @@ -399,7 +397,7 @@ m.put_int(x.co_firstlineno) m.atom_str(TYPE_STRING, x.co_lnotab) -StdObjSpace.MM.marshal_w.register(marshal_w_pycode, PyCode) +model.MM.marshal_w.register(marshal_w_pycode, PyCode) # helper for unmarshalling string lists of code objects. # unfortunately they now can be interned or referenced, Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py Mon Mar 29 19:12:45 2010 @@ -357,3 +357,32 @@ # mm.dispatch_tree = merge(self.dispatch_tree, other.dispatch_tree) return mm + + +class MM: + """StdObjSpace multimethods""" + + call = StdObjSpaceMultiMethod('call', 1, ['__call__'], + general__args__=True) + init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) + getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) + # special visible multimethods + int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int + str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string + float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float + uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) + unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters + bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint + # NOTE: when adding more sometype_w() methods, you need to write a + # stub in default.py to raise a space.w_TypeError + marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) + + # add all regular multimethods here + for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: + if _name not in locals(): + mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) + locals()[_name] = mm + del mm + + pow.extras['defaults'] = (None,) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 19:12:45 2010 @@ -8,6 +8,7 @@ from pypy.interpreter.gateway import PyPyCacheDir from pypy.tool.cache import Cache from pypy.tool.sourcetools import func_with_new_name +from pypy.objspace.std import model from pypy.objspace.std.model import W_Object, UnwrapError from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs @@ -49,20 +50,19 @@ assert self.StringObjectCls in self.model.typeorder # install all the MultiMethods into the space instance - for name, mm in self.MM.__dict__.items(): + for name, mm in model.MM.__dict__.items(): if not isinstance(mm, StdObjSpaceMultiMethod): continue if not hasattr(self, name): if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) - else: + else: exprargs, expr, miniglobals, fallback = ( mm.install_not_sliced(self.model.typeorder, baked_perform_call=False)) func = stdtypedef.make_perform_trampoline('__mm_'+name, exprargs, expr, miniglobals, mm) - # e.g. add(space, w_x, w_y) def make_boundmethod(func=func): def boundmethod(*args): @@ -76,14 +76,14 @@ fallback_name = name[len('inplace_'):] if fallback_name in ('or', 'and'): fallback_name += '_' - fallback_mm = self.MM.__dict__[fallback_name] + fallback_mm = model.MM.__dict__[fallback_name] else: fallback_mm = None builtinshortcut.install(self, mm, fallback_mm) if self.config.objspace.std.builtinshortcut: from pypy.objspace.std import builtinshortcut - builtinshortcut.install_is_true(self, self.MM.nonzero, self.MM.len) + builtinshortcut.install_is_true(self, model.MM.nonzero, model.MM.len) # set up the method cache if self.config.objspace.std.withmethodcache: @@ -529,29 +529,3 @@ 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) - init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) - getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) - # special visible multimethods - int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int - str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string - float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float - uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) - unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters - bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint - # NOTE: when adding more sometype_w() methods, you need to write a - # stub in default.py to raise a space.w_TypeError - marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) - log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) - - # add all regular multimethods here - for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if _name not in locals(): - mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) - locals()[_name] = mm - del mm - - pow.extras['defaults'] = (None,) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py Mon Mar 29 19:12:45 2010 @@ -1,3 +1,4 @@ +from pypy.objspace.std import model, stdtypedef _name_mappings = { 'and': 'and_', @@ -12,10 +13,7 @@ If the name doesn't exist then the alternative namespace is tried for registration. """ - from pypy.objspace.std.objspace import StdObjSpace - from pypy.objspace.std.model import W_ANY, W_Object - from pypy.objspace.std.stdtypedef import StdTypeDef - namespaces = list(alt_ns) + [StdObjSpace.MM, StdObjSpace] + namespaces = list(alt_ns) + [model.MM] for name, obj in module_dict.items(): if name.startswith('app_'): @@ -26,15 +24,15 @@ l=[] for i in sig.split('_'): if i == 'ANY': # just in case W_ANY is not in module_dict - icls = W_ANY + icls = model.W_ANY elif i == 'Object': # just in case W_Object is not in module_dict - icls = W_Object + icls = model.W_Object else: icls = (module_dict.get('W_%s' % i) or module_dict.get('W_%sObject' % i)) if icls is None: x = module_dict.get(i) - if isinstance(x, StdTypeDef): + if isinstance(x, stdtypedef.StdTypeDef): icls = x.any if icls is None: raise ValueError, \ @@ -115,18 +113,17 @@ We try to add them in the order defined by the OP_CORRESPONDANCES table, thus favouring swapping the arguments over negating the result. """ - from pypy.objspace.std.objspace import StdObjSpace originalentries = {} for op in OPERATORS: - originalentries[op] = getattr(StdObjSpace.MM, op).signatures() + originalentries[op] = getattr(model.MM, op).signatures() for op1, op2, correspondance in OP_CORRESPONDANCES: - mirrorfunc = getattr(StdObjSpace.MM, op2) + mirrorfunc = getattr(model.MM, op2) for types in originalentries[op1]: t1, t2 = types if t1 is t2: if not mirrorfunc.has_signature(types): - functions = getattr(StdObjSpace.MM, op1).getfunctions(types) + functions = getattr(model.MM, op1).getfunctions(types) assert len(functions) == 1, ('Automatic' ' registration of comparison functions' ' only work when there is a single method for' Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/smallintobject.py Mon Mar 29 19:12:45 2010 @@ -2,6 +2,7 @@ Implementation of small ints, stored as odd-valued pointers in the translated PyPy. To enable them, see inttype.py. """ +from pypy.interpreter.error import OperationError from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplementArgs Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py Mon Mar 29 19:12:45 2010 @@ -4,6 +4,7 @@ from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict from pypy.interpreter.baseobjspace import SpaceCache +from pypy.objspace.std import model from pypy.objspace.std.model import StdObjSpaceMultiMethod from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib import jit @@ -288,8 +289,8 @@ def slicemultimethods(space, typedef): """NOT_RPYTHON""" result = {} - # import and slice all multimethods of the space.MM container - for multimethod in hack_out_multimethods(space.MM.__dict__): + # import and slice all multimethods of the MM container + for multimethod in hack_out_multimethods(model.MM.__dict__): slicemultimethod(space, multimethod, typedef, result) # import all multimethods defined directly on the type without slicing for multimethod in typedef.local_multimethods: @@ -301,9 +302,8 @@ multimethods that have an implementation whose first typed argument is 'cls'. """ - from pypy.objspace.std.objspace import StdObjSpace # XXX for now typedef = cls.typedef - for multimethod in hack_out_multimethods(StdObjSpace.MM.__dict__): + for multimethod in hack_out_multimethods(model.MM.__dict__): if cls in multimethod.dispatch_tree: yield multimethod, False for multimethod in typedef.local_multimethods: From cfbolz at codespeak.net Mon Mar 29 19:22:03 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 19:22:03 +0200 (CEST) Subject: [pypy-svn] r73106 - in pypy/branch/reduce-instance-size-experiments/pypy/rlib: . test Message-ID: <20100329172203.29C12282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 19:22:01 2010 New Revision: 73106 Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py Log: glub. What a nonsense. Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/rerased.py Mon Mar 29 19:22:01 2010 @@ -115,7 +115,7 @@ class __extend__(pairtype(SomeErased, SomeErased)): def union((serased1, serased2)): - return serased1 + return SomeErased() class ErasedRepr(Repr): Modified: pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/rlib/test/test_rerased.py Mon Mar 29 19:22:01 2010 @@ -124,3 +124,10 @@ assert foo() is None res = interpret(foo, []) assert not res + +def test_union(): + s_e1 = SomeErased() + s_e1.const = 1 + s_e2 = SomeErased() + s_e2.const = 3 + assert not annmodel.pair(s_e1, s_e2).union().is_constant() From cfbolz at codespeak.net Mon Mar 29 19:22:41 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 19:22:41 +0200 (CEST) Subject: [pypy-svn] r73107 - pypy/branch/reduce-instance-size-experiments/pypy/objspace/std Message-ID: <20100329172241.BA515282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 19:22:40 2010 New Revision: 73107 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Log: small tweak Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 19:22:40 2010 @@ -103,8 +103,9 @@ if w_value is None: return erase(w_value) if space.is_true(space.isinstance(w_value, space.w_int)): + val = space.int_w(w_value) try: - return erase(space.int_w(w_value)) + return erase(val) except OverflowError: pass return erase(w_value) From xoraxax at codespeak.net Mon Mar 29 19:31:00 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 19:31:00 +0200 (CEST) Subject: [pypy-svn] r73108 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329173100.0F5C6282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 19:30:59 2010 New Revision: 73108 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Log: Add space argument here, let the translation fail. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/slotdefs.py Mon Mar 29 19:30:59 2010 @@ -21,7 +21,7 @@ if n == PyTuple_GET_SIZE(space, ob): return raise operationerrfmt(space.w_TypeError, - "expected %d arguments, got %zd", n, PyTuple_GET_SIZE(ob)) + "expected %d arguments, got %d", n, PyTuple_GET_SIZE(space, ob)) def wrap_unaryfunc(space, w_self, w_args, func): func_unary = rffi.cast(unaryfunc, func) From benjamin at codespeak.net Mon Mar 29 19:31:25 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 19:31:25 +0200 (CEST) Subject: [pypy-svn] r73109 - in pypy/branch/cleanup-objspace-init/pypy/objspace/std: . test Message-ID: <20100329173125.A7764282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 19:31:23 2010 New Revision: 73109 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/default.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_complexobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_floatobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_intobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_longobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_smallintobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py Log: cleanup imports Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py Mon Mar 29 19:31:23 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import interp_string_to_float, ParseStringError -from pypy.objspace.std.objspace import register_all from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef, newmethod from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/default.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/default.py Mon Mar 29 19:31:23 2010 @@ -1,6 +1,7 @@ """Default implementation for some operation.""" -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all from pypy.rlib import objectmodel Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py Mon Mar 29 19:31:23 2010 @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod from pypy.objspace.std.stdtypedef import SMM from pypy.interpreter.gateway import NoneNotWrapped Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 19:31:23 2010 @@ -1,27 +1,17 @@ -from pypy.objspace.std.register_all import register_all +import __builtin__ +from pypy.interpreter import pyframe, function from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, operationerrfmt, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter import pyframe, function +from pypy.objspace.std import stdtypedef, frame, model +from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized -from pypy.interpreter.gateway import PyPyCacheDir -from pypy.tool.cache import Cache -from pypy.tool.sourcetools import func_with_new_name -from pypy.objspace.std import model -from pypy.objspace.std.model import W_Object, UnwrapError -from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel -from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs -from pypy.objspace.descroperation import DescrOperation, raiseattrerror -from pypy.objspace.std import stdtypedef, frame from pypy.rlib.rarithmetic import base_int from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.jit import hint -import sys -import os -import __builtin__ +from pypy.tool.sourcetools import func_with_new_name -################################################################## class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object @@ -30,7 +20,7 @@ def initialize(self): "NOT_RPYTHON: only for initializing the space." # Import all the object types and implementations - self.model = StdTypeModel(self.config) + self.model = model.StdTypeModel(self.config) self.FrameClass = frame.build_frame(self) @@ -51,7 +41,7 @@ # install all the MultiMethods into the space instance for name, mm in model.MM.__dict__.items(): - if not isinstance(mm, StdObjSpaceMultiMethod): + if not isinstance(mm, model.StdObjSpaceMultiMethod): continue if not hasattr(self, name): if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object @@ -183,7 +173,7 @@ # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None - if isinstance(x, W_Object): + if isinstance(x, model.W_Object): raise TypeError, "attempt to wrap already wrapped object: %s"%(x,) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% @@ -272,13 +262,13 @@ return w_result return None wrap_exception_cls._annspecialcase_ = "override:wrap_exception_cls" - + def unwrap(self, w_obj): if isinstance(w_obj, Wrappable): return w_obj - if isinstance(w_obj, W_Object): + if isinstance(w_obj, model.W_Object): return w_obj.unwrap(self) - raise UnwrapError, "cannot unwrap: %r" % w_obj + raise model.UnwrapError, "cannot unwrap: %r" % w_obj def newint(self, intval): # this time-critical and circular-imports-funny method was stored Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py Mon Mar 29 19:31:23 2010 @@ -1,5 +1,5 @@ from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod, no_hash_descr from pypy.objspace.std.stdtypedef import SMM from pypy.interpreter.gateway import NoneNotWrapped Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_complexobject.py Mon Mar 29 19:31:23 2010 @@ -1,7 +1,7 @@ import py from pypy.objspace.std import complexobject as cobj from pypy.objspace.std import complextype as cobjtype -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std import StdObjSpace Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_floatobject.py Mon Mar 29 19:31:23 2010 @@ -1,5 +1,5 @@ from pypy.objspace.std import floatobject as fobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement import py class TestW_FloatObject: Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_intobject.py Mon Mar 29 19:31:23 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import intobject as iobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_longobject.py Mon Mar 29 19:31:23 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import longobject as lobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_smallintobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_smallintobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_smallintobject.py Mon Mar 29 19:31:23 2010 @@ -5,7 +5,7 @@ # py.test.skip("WITHSMALLINT is not enabled") from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint from pypy.objspace.std.test.test_intobject import AppTestInt Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py Mon Mar 29 19:31:23 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import * -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod from pypy.conftest import gettestobjspace from pypy.objspace.std.typeobject import W_TypeObject From getxsick at codespeak.net Mon Mar 29 19:32:15 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 19:32:15 +0200 (CEST) Subject: [pypy-svn] r73110 - pypy/build/ubuntu/trunk Message-ID: <20100329173215.B8ABF282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 19:32:14 2010 New Revision: 73110 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: more env vars Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 19:32:14 2010 @@ -8,6 +8,7 @@ export DEBFULLNAME="Bartosz Skowron" export DEBEMAIL="getxsick at gmail.com" +export USER="getxsick" ( From getxsick at codespeak.net Mon Mar 29 19:33:06 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 19:33:06 +0200 (CEST) Subject: [pypy-svn] r73111 - pypy/build/ubuntu/trunk Message-ID: <20100329173306.DE458282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 19:33:05 2010 New Revision: 73111 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: correct filename of .changes file Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 19:33:05 2010 @@ -60,7 +60,7 @@ cd .. echo " -- Upload a package" - dput pypy-weekly pypy-$NEXT_RELEASE~$SVNTAG-0${dist}1_source.changes + dput pypy-weekly pypy_$NEXT_RELEASE~$SVNTAG-0${dist}1_source.changes done rm changelog.old From benjamin at codespeak.net Mon Mar 29 19:33:23 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 19:33:23 +0200 (CEST) Subject: [pypy-svn] r73112 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329173323.796DF282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 19:33:21 2010 New Revision: 73112 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: kill ugly whitespace Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 19:33:21 2010 @@ -96,8 +96,8 @@ self.w_False = W_BoolObject.w_False self.w_True = W_BoolObject.w_True from pypy.interpreter.special import NotImplemented, Ellipsis - self.w_NotImplemented = self.wrap(NotImplemented(self)) - self.w_Ellipsis = self.wrap(Ellipsis(self)) + self.w_NotImplemented = self.wrap(NotImplemented(self)) + self.w_Ellipsis = self.wrap(Ellipsis(self)) # types for typedef in self.model.pythontypes: @@ -110,14 +110,14 @@ # the type of old-style classes self.w_classobj = self.builtin.get('__metaclass__') - # fix up a problem where multimethods apparently don't - # like to define this at interp-level + # fix up a problem where multimethods apparently don't + # like to define this at interp-level # HACK HACK HACK from pypy.objspace.std.typeobject import _HEAPTYPE old_flags = self.w_dict.__flags__ self.w_dict.__flags__ |= _HEAPTYPE self.appexec([self.w_dict], """ - (dict): + (dict): def fromkeys(cls, seq, value=None): r = cls() for s in seq: @@ -133,7 +133,7 @@ if self.config.objspace.std.withtproxy: w___pypy__ = self.getbuiltinmodule("__pypy__") from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - + self.setattr(w___pypy__, self.wrap('tproxy'), self.wrap(app_proxy)) self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), @@ -249,7 +249,6 @@ w_result = self.wrap_exception_cls(x) if w_result is not None: return w_result - #print "fake-wrapping", x from fake import fake_object return fake_object(self, x) @@ -258,7 +257,7 @@ def wrap_exception_cls(self, x): """NOT_RPYTHON""" if hasattr(self, 'w_' + x.__name__): - w_result = getattr(self, 'w_' + x.__name__) + w_result = getattr(self, 'w_' + x.__name__) return w_result return None wrap_exception_cls._annspecialcase_ = "override:wrap_exception_cls" From fijal at codespeak.net Mon Mar 29 19:48:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 29 Mar 2010 19:48:06 +0200 (CEST) Subject: [pypy-svn] r73113 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100329174806.7E879282B9D@codespeak.net> Author: fijal Date: Mon Mar 29 19:48:03 2010 New Revision: 73113 Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/patchlevel.h Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Log: Include patchlevel.h. Numbers might require small tweaks Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Mon Mar 29 19:48:03 2010 @@ -18,6 +18,8 @@ #endif #define Py_ssize_t long +#include "patchlevel.h" + #include "object.h" /* move somewhere else */ Added: pypy/branch/cpython-extension/pypy/module/cpyext/include/patchlevel.h ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/patchlevel.h Mon Mar 29 19:48:03 2010 @@ -0,0 +1,40 @@ + +/* Newfangled version identification scheme. + + This scheme was added in Python 1.5.2b2; before that time, only PATCHLEVEL + was available. To test for presence of the scheme, test for + defined(PY_MAJOR_VERSION). + + When the major or minor version changes, the VERSION variable in + configure.in must also be changed. + + There is also (independent) API version information in modsupport.h. +*/ + +/* Values for PY_RELEASE_LEVEL */ +#define PY_RELEASE_LEVEL_ALPHA 0xA +#define PY_RELEASE_LEVEL_BETA 0xB +#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ +#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ + /* Higher for patch releases */ + +/* Version parsed out into numeric values */ +#define PY_MAJOR_VERSION 2 +#define PY_MINOR_VERSION 5 +#define PY_MICRO_VERSION 5 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 + +/* Version as a string */ +#define PY_VERSION "2.5.5" + +/* Subversion Revision number of this file (not of the repository) */ +#define PY_PATCHLEVEL_REVISION "$Revision: 77872 $" + +/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. + Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ +#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ + (PY_MINOR_VERSION << 16) | \ + (PY_MICRO_VERSION << 8) | \ + (PY_RELEASE_LEVEL << 4) | \ + (PY_RELEASE_SERIAL << 0)) From benjamin at codespeak.net Mon Mar 29 20:00:48 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 20:00:48 +0200 (CEST) Subject: [pypy-svn] r73114 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329180048.74E34282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 20:00:46 2010 New Revision: 73114 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py Log: cleanup import dependencies Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py Mon Mar 29 20:00:46 2010 @@ -1,10 +1,10 @@ from pypy.interpreter.error import OperationError, operationerrfmt +from pypy.interpreter.typedef import GetSetProperty from pypy.objspace.descroperation import Object from pypy.interpreter import gateway from pypy.interpreter.typedef import default_identity_hash -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.objspace import StdObjSpace def descr__repr__(space, w_obj): From benjamin at codespeak.net Mon Mar 29 20:01:40 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 20:01:40 +0200 (CEST) Subject: [pypy-svn] r73115 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329180140.189D7282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 20:01:38 2010 New Revision: 73115 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: move imports out of initialize() and kill globals hack Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 20:01:38 2010 @@ -1,9 +1,10 @@ import __builtin__ -from pypy.interpreter import pyframe, function +from pypy.interpreter import pyframe, function, special from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.objspace.std import stdtypedef, frame, model +from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, + typeobject) from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized @@ -12,6 +13,25 @@ from pypy.rlib.jit import hint from pypy.tool.sourcetools import func_with_new_name +# Object imports +from pypy.objspace.std.boolobject import W_BoolObject +from pypy.objspace.std.complexobject import W_ComplexObject +from pypy.objspace.std.dictmultiobject import W_DictMultiObject +from pypy.objspace.std.floatobject import W_FloatObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.longobject import W_LongObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.ropeobject import W_RopeObject +from pypy.objspace.std.iterobject import W_SeqIterObject +from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.smallintobject import W_SmallIntObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.transparent import app_proxy, app_proxy_controller +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.typeobject import W_TypeObject + class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object @@ -25,18 +45,14 @@ self.FrameClass = frame.build_frame(self) # store the dict class on the space to access it in various places - from pypy.objspace.std import dictmultiobject - self.DictObjectCls = dictmultiobject.W_DictMultiObject + self.DictObjectCls = W_DictMultiObject - from pypy.objspace.std import tupleobject - self.TupleObjectCls = tupleobject.W_TupleObject + self.TupleObjectCls = W_TupleObject if not self.config.objspace.std.withrope: - from pypy.objspace.std import stringobject - self.StringObjectCls = stringobject.W_StringObject + self.StringObjectCls = W_StringObject else: - from pypy.objspace.std import ropeobject - self.StringObjectCls = ropeobject.W_RopeObject + self.StringObjectCls = W_RopeObject assert self.StringObjectCls in self.model.typeorder # install all the MultiMethods into the space instance @@ -72,7 +88,6 @@ builtinshortcut.install(self, mm, fallback_mm) if self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut builtinshortcut.install_is_true(self, model.MM.nonzero, model.MM.len) # set up the method cache @@ -85,19 +100,12 @@ self.method_cache_hits = {} self.method_cache_misses = {} - # hack to avoid imports in the time-critical functions below - for cls in self.model.typeorder: - globals()[cls.__name__] = cls - for cls in self.model.imported_but_not_registered: - globals()[cls.__name__] = cls - # singletons self.w_None = W_NoneObject.w_None self.w_False = W_BoolObject.w_False self.w_True = W_BoolObject.w_True - from pypy.interpreter.special import NotImplemented, Ellipsis - self.w_NotImplemented = self.wrap(NotImplemented(self)) - self.w_Ellipsis = self.wrap(Ellipsis(self)) + self.w_NotImplemented = self.wrap(special.NotImplemented(self)) + self.w_Ellipsis = self.wrap(special.Ellipsis(self)) # types for typedef in self.model.pythontypes: @@ -113,9 +121,8 @@ # fix up a problem where multimethods apparently don't # like to define this at interp-level # HACK HACK HACK - from pypy.objspace.std.typeobject import _HEAPTYPE old_flags = self.w_dict.__flags__ - self.w_dict.__flags__ |= _HEAPTYPE + self.w_dict.__flags__ |= typeobject._HEAPTYPE self.appexec([self.w_dict], """ (dict): def fromkeys(cls, seq, value=None): @@ -132,8 +139,6 @@ # Adding transparent proxy call if self.config.objspace.std.withtproxy: w___pypy__ = self.getbuiltinmodule("__pypy__") - from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - self.setattr(w___pypy__, self.wrap('tproxy'), self.wrap(app_proxy)) self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), From xoraxax at codespeak.net Mon Mar 29 20:12:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 20:12:03 +0200 (CEST) Subject: [pypy-svn] r73116 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329181203.9AE16282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 20:12:01 2010 New Revision: 73116 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Use _isllptr here. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 20:12:01 2010 @@ -152,7 +152,7 @@ arg = input_arg elif ARG is PyObject and is_wrapped: # convert to a wrapped object - if not isinstance(input_arg, W_Root): + if rffi._isllptr(input_arg): arg = from_ref(space, input_arg) else: arg = input_arg From xoraxax at codespeak.net Mon Mar 29 20:12:18 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 20:12:18 +0200 (CEST) Subject: [pypy-svn] r73117 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329181218.7B5E4282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 20:12:17 2010 New Revision: 73117 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Log: get needs a None. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Mon Mar 29 20:12:17 2010 @@ -28,7 +28,7 @@ del state.py_objects_w2r[w_obj] if ptr in state.borrow_mapping: for containee in state.borrow_mapping[ptr]: - w_containee = state.py_objects_r2w.get(containee) + w_containee = state.py_objects_r2w.get(containee, None) if w_containee is not None: containee = state.py_objects_w2r[w_containee] Py_DECREF(space, w_containee) From fijal at codespeak.net Mon Mar 29 20:13:22 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Mon, 29 Mar 2010 20:13:22 +0200 (CEST) Subject: [pypy-svn] r73118 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329181322.C6EDA282B9D@codespeak.net> Author: fijal Date: Mon Mar 29 20:13:21 2010 New Revision: 73118 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Log: Use better interface here Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Mon Mar 29 20:13:21 2010 @@ -15,7 +15,7 @@ space.is_true(space.isinstance(w_obj, space.w_tuple))): return w_obj try: - return space.newtuple(space.unpackiterable(w_obj)) + return space.newtuple(space.fixedview(w_obj)) except OperationError: raise OperationError(space.w_TypeError, space.wrap(rffi.charp2str(m))) From xoraxax at codespeak.net Mon Mar 29 20:14:18 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 20:14:18 +0200 (CEST) Subject: [pypy-svn] r73119 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329181418.47742282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 20:14:17 2010 New Revision: 73119 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: (amaury) some changes by amaury to rpythonify code. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Mon Mar 29 20:14:17 2010 @@ -392,12 +392,14 @@ def make_wrapper(space, callable): names = callable.api_func.argnames argtypes_enum_ui = unrolling_iterable(enumerate(zip(callable.api_func.argtypes, - names, [name.startswith("w_") for name in names]))) + [name.startswith("w_") for name in names]))) + + @specialize.ll() def wrapper(*args): boxed_args = () if DEBUG_WRAPPER: print >>sys.stderr, callable, - for i, (typ, argname, is_wrapped) in argtypes_enum_ui: + for i, (typ, is_wrapped) in argtypes_enum_ui: arg = args[i] if (typ is PyObject and is_wrapped): @@ -655,7 +657,9 @@ result = func(*boxed_args) try: if RESULT_TYPE is PyObject: - if isinstance(result, W_Root): + if result is None: + ret = result + elif isinstance(result, W_Root): ret = result else: ret = from_ref(space, result) From cfbolz at codespeak.net Mon Mar 29 20:16:20 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Mar 2010 20:16:20 +0200 (CEST) Subject: [pypy-svn] r73120 - in pypy/branch/reduce-instance-size-experiments/pypy/objspace/std: . test Message-ID: <20100329181620.E5A9D282B9D@codespeak.net> Author: cfbolz Date: Mon Mar 29 20:16:19 2010 New Revision: 73120 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py Log: pf, don't erase subclasses of int Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/sharingdict.py Mon Mar 29 20:16:19 2010 @@ -94,15 +94,13 @@ return structure.find_structure_del_key(num_back) - - def erase(space, w_value): if not space.config.objspace.std.withsharingtaggingdict: return w_value from pypy.rlib.rerased import erase if w_value is None: return erase(w_value) - if space.is_true(space.isinstance(w_value, space.w_int)): + if space.is_w(space.type(w_value), space.w_int): val = space.int_w(w_value) try: return erase(val) @@ -162,8 +160,8 @@ attr.setfield(self.entries, w_value) return new_structure = self.structure.get_next_structure(key) - self.entries = self.structure.convert_to(new_structure, self.entries) attr = new_structure.lookup_attribute(key) + self.entries = self.structure.convert_to(new_structure, self.entries) attr.setfield(self.entries, w_value) self.structure = new_structure Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_sharingdict.py Mon Mar 29 20:16:19 2010 @@ -36,6 +36,23 @@ def key_positions(d): return dict([(key, attr.index) for key, attr in d.structure.keys.items()]) +def test_erase_int_subclass(): + class FakeSpace: + class config: + class objspace: + class std: + withsharingdict = True + withsharingtaggingdict = True + is_true = bool + isinstance = isinstance + w_int = int + int_w = int + wrap = lambda self, x: x + is_w = lambda self, a, b: a is b + type = type + space = FakeSpace() + assert unerase(space, erase(space, True)) is True + def test_delete(): space = FakeSpace() d = SharedDictImplementation(space) From afa at codespeak.net Mon Mar 29 20:19:36 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Mon, 29 Mar 2010 20:19:36 +0200 (CEST) Subject: [pypy-svn] r73121 - pypy/branch/cpython-extension/pypy/rpython Message-ID: <20100329181936.8435D282BD6@codespeak.net> Author: afa Date: Mon Mar 29 20:19:34 2010 New Revision: 73121 Modified: pypy/branch/cpython-extension/pypy/rpython/annlowlevel.py Log: Gives KeyComp a better __repr__ to be displayed in lists --Cette ligne, et les suivantes ci-dessous, seront ignor?es-- M annlowlevel.py Modified: pypy/branch/cpython-extension/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/annlowlevel.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/annlowlevel.py Mon Mar 29 20:19:34 2010 @@ -34,6 +34,7 @@ else: s = compact() return s + 'Const' + __repr__ = __str__ class LowLevelAnnotatorPolicy(AnnotatorPolicy): allow_someobjects = False From getxsick at codespeak.net Mon Mar 29 20:27:48 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 20:27:48 +0200 (CEST) Subject: [pypy-svn] r73122 - pypy/build/ubuntu/trunk Message-ID: <20100329182748.CFA55282BD6@codespeak.net> Author: getxsick Date: Mon Mar 29 20:27:47 2010 New Revision: 73122 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: use my special GPG and drop gpg-agent Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 20:27:47 2010 @@ -6,28 +6,11 @@ LOGFILE="autobuild.log" NEXT_RELEASE=1.3 -export DEBFULLNAME="Bartosz Skowron" +export DEBFULLNAME="Bartosz Skowron's Daily Debs" export DEBEMAIL="getxsick at gmail.com" export USER="getxsick" ( - -if !([ -f "$HOME/.gpg-agent-info" ] && \ - kill -0 `cut -d: -f 2 $HOME/.gpg-agent-info` 2>/dev/null) -then - # XXX runing gpg-agent doesn't make more sense, cause we need - # to type the passphrase (for first signing) - # - # i have no idea how to avoid it and the only known for me way is - # to send email notification to do it manually ;) - echo "--- gpg-agent is down, send the email notification /`date -R`/" - #eval `gpg-agent --daemon > $HOME/.gpg-agent-info` - echo "`date -R` : gpg-agent is down." | \ - mail -s "[pypy-autobuild] gpg-agent is down" $DEBEMAIL - exit 10 -fi -. "$HOME/.gpg-agent-info" - echo "--- Start a new build at `date -R`" echo " -- Check out pypy trunk" From getxsick at codespeak.net Mon Mar 29 20:28:53 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 20:28:53 +0200 (CEST) Subject: [pypy-svn] r73123 - pypy/build/ubuntu/trunk Message-ID: <20100329182853.95304282BD6@codespeak.net> Author: getxsick Date: Mon Mar 29 20:28:52 2010 New Revision: 73123 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: fix redirection. &> doesn't work under sh Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 20:28:52 2010 @@ -51,4 +51,4 @@ echo "`date -R` : Packages built and sent successfully." | \ mail -s "[pypy-autobuild] status" $DEBEMAIL echo "--- Finish the new build at `date -R`" -) &>>$LOGFILE +) >>$LOGFILE 2>&1 From benjamin at codespeak.net Mon Mar 29 20:46:40 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 20:46:40 +0200 (CEST) Subject: [pypy-svn] r73124 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329184640.0CB79282BD6@codespeak.net> Author: benjamin Date: Mon Mar 29 20:46:39 2010 New Revision: 73124 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: dict.fromkeys becomes interp level, killing the evil app hack Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py Mon Mar 29 20:46:39 2010 @@ -1,3 +1,5 @@ +from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all @@ -124,7 +126,6 @@ def itervalues(d): return iter(dict.values(d)) ''', filename=__file__) -#XXX what about dict.fromkeys()? dict_update__ANY = app.interphook("update") dict_popitem__ANY = app.interphook("popitem") @@ -138,6 +139,24 @@ register_all(vars(), globals()) + at gateway.unwrap_spec(ObjSpace, W_Root, W_Root, W_Root) +def descr_fromkeys(space, w_type, w_keys, w_fill=None): + from pypy.objspace.std.dictmultiobject import W_DictMultiObject + if w_fill is None: + w_fill = space.w_None + w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type) + w_iter = space.iter(w_keys) + while True: + try: + w_key = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + space.setitem(w_dict, w_key, w_fill) + return w_dict + + # ____________________________________________________________ def descr__new__(space, w_dicttype, __args__): @@ -160,6 +179,7 @@ __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), __hash__ = no_hash_descr, + fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True), ) dict_typedef.registermethods(globals()) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 20:46:39 2010 @@ -3,8 +3,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, - typeobject) +from pypy.objspace.std import builtinshortcut, stdtypedef, frame, model from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized @@ -118,22 +117,6 @@ # the type of old-style classes self.w_classobj = self.builtin.get('__metaclass__') - # fix up a problem where multimethods apparently don't - # like to define this at interp-level - # HACK HACK HACK - old_flags = self.w_dict.__flags__ - self.w_dict.__flags__ |= typeobject._HEAPTYPE - self.appexec([self.w_dict], """ - (dict): - def fromkeys(cls, seq, value=None): - r = cls() - for s in seq: - r[s] = value - return r - dict.fromkeys = classmethod(fromkeys) - """) - self.w_dict.__flags__ = old_flags - # final setup self.setup_builtin_modules() # Adding transparent proxy call From benjamin at codespeak.net Mon Mar 29 20:47:44 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 20:47:44 +0200 (CEST) Subject: [pypy-svn] r73125 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329184744.08E4F282BD6@codespeak.net> Author: benjamin Date: Mon Mar 29 20:47:43 2010 New Revision: 73125 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: these assignments needn't line up Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 20:47:43 2010 @@ -100,9 +100,9 @@ self.method_cache_misses = {} # singletons - self.w_None = W_NoneObject.w_None + self.w_None = W_NoneObject.w_None self.w_False = W_BoolObject.w_False - self.w_True = W_BoolObject.w_True + self.w_True = W_BoolObject.w_True self.w_NotImplemented = self.wrap(special.NotImplemented(self)) self.w_Ellipsis = self.wrap(special.Ellipsis(self)) From xoraxax at codespeak.net Mon Mar 29 21:00:39 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Mon, 29 Mar 2010 21:00:39 +0200 (CEST) Subject: [pypy-svn] r73126 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329190039.0164A282B9D@codespeak.net> Author: xoraxax Date: Mon Mar 29 21:00:38 2010 New Revision: 73126 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Log: Add cast and correctly pass nullptr. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Mon Mar 29 21:00:38 2010 @@ -27,10 +27,11 @@ @cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef), rffi.CCHARP, PyObject, rffi.INT_real], PyObject, borrowed=False) # we cannot borrow here def Py_InitModule4(space, name, methods, doc, w_self, apiver): + from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr modname = rffi.charp2str(name) w_mod = PyImport_AddModule(space, modname) dict_w = {} - convert_method_defs(space, dict_w, methods, None, w_self) + convert_method_defs(space, dict_w, methods, lltype.nullptr(PyTypeObjectPtr.TO), w_self) for key, w_value in dict_w.items(): space.setattr(w_mod, space.wrap(key), w_value) if doc: @@ -49,7 +50,7 @@ if not method.c_ml_name: break methodname = rffi.charp2str(method.c_ml_name) - flags = method.c_ml_flags + flags = rffi.cast(lltype.Signed, method.c_ml_flags) if pto is None: if flags & METH_CLASS or flags & METH_STATIC: raise OperationError(space.w_ValueError, From benjamin at codespeak.net Mon Mar 29 21:19:47 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 21:19:47 +0200 (CEST) Subject: [pypy-svn] r73127 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329191947.3D019282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 21:19:39 2010 New Revision: 73127 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/transparent.py Log: move some parts of initialize() to helpers Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 21:19:39 2010 @@ -1,9 +1,11 @@ import __builtin__ +import types from pypy.interpreter import pyframe, function, special from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.objspace.std import builtinshortcut, stdtypedef, frame, model +from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, + transparent) from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized @@ -27,7 +29,6 @@ from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std.smallintobject import W_SmallIntObject from pypy.objspace.std.stringobject import W_StringObject -from pypy.objspace.std.transparent import app_proxy, app_proxy_controller from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.typeobject import W_TypeObject @@ -38,7 +39,7 @@ def initialize(self): "NOT_RPYTHON: only for initializing the space." - # Import all the object types and implementations + # setup all the object types and implementations self.model = model.StdTypeModel(self.config) self.FrameClass = frame.build_frame(self) @@ -54,50 +55,10 @@ self.StringObjectCls = W_RopeObject assert self.StringObjectCls in self.model.typeorder - # install all the MultiMethods into the space instance - for name, mm in model.MM.__dict__.items(): - if not isinstance(mm, model.StdObjSpaceMultiMethod): - continue - if not hasattr(self, name): - if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object - func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) - else: - exprargs, expr, miniglobals, fallback = ( - mm.install_not_sliced(self.model.typeorder, baked_perform_call=False)) - - func = stdtypedef.make_perform_trampoline('__mm_'+name, - exprargs, expr, miniglobals, - mm) - # e.g. add(space, w_x, w_y) - def make_boundmethod(func=func): - def boundmethod(*args): - return func(self, *args) - return func_with_new_name(boundmethod, 'boundmethod_'+name) - boundmethod = make_boundmethod() - setattr(self, name, boundmethod) # store into 'space' instance - elif self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut - if name.startswith('inplace_'): - fallback_name = name[len('inplace_'):] - if fallback_name in ('or', 'and'): - fallback_name += '_' - fallback_mm = model.MM.__dict__[fallback_name] - else: - fallback_mm = None - builtinshortcut.install(self, mm, fallback_mm) + self._install_multimethods() - if self.config.objspace.std.builtinshortcut: - builtinshortcut.install_is_true(self, model.MM.nonzero, model.MM.len) - - # set up the method cache if self.config.objspace.std.withmethodcache: - SIZE = 1 << self.config.objspace.std.methodcachesizeexp - self.method_cache_versions = [None] * SIZE - self.method_cache_names = [None] * SIZE - self.method_cache_lookup_where = [(None, None)] * SIZE - if self.config.objspace.std.withmethodcachecounter: - self.method_cache_hits = {} - self.method_cache_misses = {} + self._setup_method_cache() # singletons self.w_None = W_NoneObject.w_None @@ -121,11 +82,49 @@ self.setup_builtin_modules() # Adding transparent proxy call if self.config.objspace.std.withtproxy: - w___pypy__ = self.getbuiltinmodule("__pypy__") - self.setattr(w___pypy__, self.wrap('tproxy'), - self.wrap(app_proxy)) - self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), - self.wrap(app_proxy_controller)) + transparent.setup(self) + + def _setup_method_cache(self): + SIZE = 1 << self.config.objspace.std.methodcachesizeexp + self.method_cache_versions = [None] * SIZE + self.method_cache_names = [None] * SIZE + self.method_cache_lookup_where = [(None, None)] * SIZE + if self.config.objspace.std.withmethodcachecounter: + self.method_cache_hits = {} + self.method_cache_misses = {} + + def _install_multimethods(self): + """Install all the MultiMethods into the space instance.""" + for name, mm in model.MM.__dict__.items(): + if not isinstance(mm, model.StdObjSpaceMultiMethod): + continue + if not hasattr(self, name): + # int_w, str_w...: these do not return a wrapped object + if name.endswith('_w'): + func = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=True) + else: + unsliced = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=False) + exprargs, expr, miniglobals, fallback = unsliced + func = stdtypedef.make_perform_trampoline('__mm_'+name, + exprargs, expr, + miniglobals, mm) + + boundmethod = types.MethodType(func, self, self.__class__) + setattr(self, name, boundmethod) # store into 'space' instance + elif self.config.objspace.std.builtinshortcut: + if name.startswith('inplace_'): + fallback_name = name[len('inplace_'):] + if fallback_name in ('or', 'and'): + fallback_name += '_' + fallback_mm = model.MM.__dict__[fallback_name] + else: + fallback_mm = None + builtinshortcut.install(self, mm, fallback_mm) + if self.config.objspace.std.builtinshortcut: + builtinshortcut.install_is_true(self, model.MM.nonzero, + model.MM.len) def createexecutioncontext(self): # add space specific fields to execution context Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/transparent.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/transparent.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/transparent.py Mon Mar 29 21:19:39 2010 @@ -20,6 +20,16 @@ type_cache = TypeCache() + +def setup(space): + """Add proxy functions to the __pypy__ module.""" + w___pypy__ = space.getbuiltinmodule("__pypy__") + space.setattr(w___pypy__, space.wrap('tproxy'), space.wrap(app_proxy)) + space.setattr(w___pypy__, space.wrap('get_tproxy_controller'), + space.wrap(app_proxy_controller)) + + + def proxy(space, w_type, w_controller): """tproxy(typ, controller) -> obj Return something that looks like it is of type typ. Its behaviour is From benjamin at codespeak.net Mon Mar 29 21:24:33 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 21:24:33 +0200 (CEST) Subject: [pypy-svn] r73128 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329192433.B3D8A282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 21:24:32 2010 New Revision: 73128 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/__init__.py Log: qualify import Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/__init__.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/__init__.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/__init__.py Mon Mar 29 21:24:32 2010 @@ -1,2 +1,2 @@ -from objspace import StdObjSpace +from pypy.objspace.std.objspace import StdObjSpace Space = StdObjSpace From benjamin at codespeak.net Mon Mar 29 21:31:22 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 21:31:22 +0200 (CEST) Subject: [pypy-svn] r73129 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329193122.DF4F6282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 21:31:20 2010 New Revision: 73129 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: remove more imports from functions Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 21:31:20 2010 @@ -5,7 +5,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, - transparent) + transparent, callmethod) from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized @@ -32,6 +32,12 @@ from pypy.objspace.std.tupleobject import W_TupleObject from pypy.objspace.std.typeobject import W_TypeObject +# types +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.stringtype import wrapstr +from pypy.objspace.std.tupletype import wraptuple +from pypy.objspace.std.unicodetype import wrapunicode + class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object @@ -171,10 +177,8 @@ else: return self.newint(x) if isinstance(x, str): - from pypy.objspace.std.stringtype import wrapstr return wrapstr(self, x) if isinstance(x, unicode): - from pypy.objspace.std.unicodetype import wrapunicode return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) @@ -260,7 +264,6 @@ # this time-critical and circular-imports-funny method was stored # on 'self' by initialize() # not sure how bad this is: - from pypy.objspace.std.inttype import wrapint return wrapint(self, intval) def newfloat(self, floatval): @@ -273,18 +276,15 @@ return W_LongObject.fromint(self, val) def newtuple(self, list_w): - from pypy.objspace.std.tupletype import wraptuple assert isinstance(list_w, list) make_sure_not_resized(list_w) return wraptuple(self, list_w) def newlist(self, list_w): - from pypy.objspace.std.listobject import W_ListObject return W_ListObject(list_w) def newdict(self, module=False, instance=False, classofinstance=None, from_strdict_shared=None, strdict=False): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject return W_DictMultiObject.allocate_and_init_instance( self, module=module, instance=instance, classofinstance=classofinstance, @@ -497,8 +497,7 @@ def call_method(self, w_obj, methname, *arg_w): if self.config.objspace.opcodes.CALL_METHOD: - from pypy.objspace.std.callmethod import call_method_opt - return call_method_opt(self, w_obj, methname, *arg_w) + return callmethod.call_method_opt(self, w_obj, methname, *arg_w) else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) From arigo at codespeak.net Mon Mar 29 21:35:13 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 21:35:13 +0200 (CEST) Subject: [pypy-svn] r73130 - in pypy/trunk: . dotviewer lib-python pypy pypy/interpreter pypy/interpreter/test pypy/jit/backend/cli/test pypy/jit/backend/llvm/test pypy/jit/backend/x86/test pypy/jit/metainterp pypy/module/_sre pypy/module/exceptions pypy/objspace/flow pypy/objspace/std/test pypy/rlib pypy/rlib/test pypy/rpython pypy/translator pypy/translator/c pypy/translator/c/src pypy/translator/c/test pypy/translator/stackless Message-ID: <20100329193513.A5D8C282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 21:35:09 2010 New Revision: 73130 Added: pypy/trunk/pypy/rlib/rstackovf.py - copied unchanged from r73128, pypy/branch/stackovf/pypy/rlib/rstackovf.py pypy/trunk/pypy/rlib/test/test_rstackovf.py - copied unchanged from r73128, pypy/branch/stackovf/pypy/rlib/test/test_rstackovf.py Modified: pypy/trunk/ (props changed) pypy/trunk/dotviewer/ (props changed) pypy/trunk/lib-python/ (props changed) pypy/trunk/pypy/ (props changed) pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/pyopcode.py pypy/trunk/pypy/interpreter/test/test_interpreter.py pypy/trunk/pypy/jit/backend/cli/test/conftest.py (props changed) pypy/trunk/pypy/jit/backend/llvm/test/conftest.py (props changed) pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (props changed) pypy/trunk/pypy/jit/metainterp/logger.py (props changed) pypy/trunk/pypy/module/_sre/interp_sre.py pypy/trunk/pypy/module/exceptions/ (props changed) pypy/trunk/pypy/objspace/flow/objspace.py pypy/trunk/pypy/objspace/std/test/test_setobject.py (props changed) pypy/trunk/pypy/rlib/rzipfile.py pypy/trunk/pypy/rlib/test/test_rcoroutine.py (props changed) pypy/trunk/pypy/rpython/exceptiondata.py pypy/trunk/pypy/rpython/llinterp.py pypy/trunk/pypy/translator/c/node.py pypy/trunk/pypy/translator/c/src/exception.h pypy/trunk/pypy/translator/c/test/test_refcount.py (props changed) pypy/trunk/pypy/translator/exceptiontransform.py pypy/trunk/pypy/translator/stackless/code.py Log: Merge branch/stackovf: introduce the StackOverflow exception. It is a subclass of RuntimeError, raised in RPython programs for stack overflows, and defined in pypy.rlib.rstackovf. There is a bit of magic in pypy.rlib.rstackovf to let you say "except StackOverflow:" and still have it caught when running untranslated (in which case you get of course just CPython's RuntimeError). But it allows some cleanups a bit here and there, and "pypy-c" now can confidently print "RuntimeError: maximum recursion depth exceeded" instead of "RuntimeError: internal error (stack overflow?)". Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Mon Mar 29 21:35:09 2010 @@ -22,6 +22,7 @@ from pypy.interpreter.argument import Arguments, Signature from pypy.tool.sourcetools import NiceCompile, compile2 from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.rlib import rstackovf # internal non-translatable parts: import py @@ -548,27 +549,32 @@ func.defs_w, self.minargs) try: w_result = activation._run(space, scope_w) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, - space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: if w_obj is not None: args = args.prepend(w_obj) return scope_w[0].descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result + def handle_exception(self, space, e): + try: + raise e + except KeyboardInterrupt: + raise OperationError(space.w_KeyboardInterrupt, + space.w_None) + except MemoryError: + raise OperationError(space.w_MemoryError, space.w_None) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow(e) + raise OperationError(space.w_RuntimeError, + space.wrap("maximum recursion depth exceeded")) + # (verbose) performance hack below class BuiltinCodePassThroughArguments0(BuiltinCode): @@ -578,20 +584,13 @@ space = func.space try: w_result = self.func__args__(space, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -604,20 +603,13 @@ space = func.space try: w_result = self.func__args__(space, w_obj, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args.prepend(w_obj)) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -629,15 +621,11 @@ def fastcall_0(self, space, w_func): try: w_result = self.fastfunc_0(space) - except KeyboardInterrupt: - 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))) + except DescrMismatch: + raise OperationError(space.w_SystemError, + space.wrap("unexpected DescrMismatch error")) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -649,20 +637,13 @@ def fastcall_1(self, space, w_func, w1): try: w_result = self.fastfunc_1(space, w1) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -674,20 +655,13 @@ def fastcall_2(self, space, w_func, w1, w2): try: w_result = self.fastfunc_2(space, w1, w2) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -699,20 +673,13 @@ def fastcall_3(self, space, func, w1, w2, w3): try: w_result = self.fastfunc_3(space, w1, w2, w3) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -724,21 +691,14 @@ def fastcall_4(self, space, func, w1, w2, w3, w4): try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3, w4])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Mon Mar 29 21:35:09 2010 @@ -18,6 +18,7 @@ from pypy.tool.stdlib_opcode import unrolling_opcode_descs from pypy.tool.stdlib_opcode import opcode_method_names from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib import rstackovf def unaryoperation(operationname): """NOT_RPYTHON""" @@ -106,20 +107,13 @@ 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 - # in translated PyPy - msg = "internal error (stack overflow?)" - else: - msg = str(e) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow(e) next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, - self.space.wrap(msg)) + self.space.wrap("maximum recursion depth exceeded")) return next_instr - + def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them # into OperationErrors Modified: pypy/trunk/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/trunk/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/trunk/pypy/interpreter/test/test_interpreter.py Mon Mar 29 21:35:09 2010 @@ -263,3 +263,12 @@ def test_identity(self): def f(x): return x assert f(666) == 666 + + def test_raise_recursion(self): + def f(): f() + try: + f() + except RuntimeError, e: + assert str(e) == "maximum recursion depth exceeded" + else: + assert 0, "should have raised!" Modified: pypy/trunk/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/trunk/pypy/module/_sre/interp_sre.py (original) +++ pypy/trunk/pypy/module/_sre/interp_sre.py Mon Mar 29 21:35:09 2010 @@ -177,10 +177,20 @@ state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.search(pattern_codes)) + try: + res = state.search(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) def w_match(space, w_state, w_pattern_codes): state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.match(pattern_codes)) + try: + res = state.match(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Mon Mar 29 21:35:09 2010 @@ -8,6 +8,7 @@ from pypy.objspace.flow import flowcontext from pypy.objspace.flow.operation import FunctionByName from pypy.rlib.unroll import unrolling_iterable, _unroller +from pypy.rlib import rstackovf debug = 0 @@ -201,9 +202,13 @@ if not isinstance(check_class, tuple): # the simple case return ObjSpace.exception_match(self, w_exc_type, w_check_class) + # special case for StackOverflow (see rlib/rstackovf.py) + if check_class == rstackovf.StackOverflow: + w_real_class = self.wrap(rstackovf._StackOverflow) + return ObjSpace.exception_match(self, w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): - if ObjSpace.exception_match(self, w_exc_type, w_klass): + if self.exception_match(w_exc_type, w_klass): return True return False Modified: pypy/trunk/pypy/rlib/rzipfile.py ============================================================================== --- pypy/trunk/pypy/rlib/rzipfile.py (original) +++ pypy/trunk/pypy/rlib/rzipfile.py Mon Mar 29 21:35:09 2010 @@ -217,7 +217,7 @@ + fheader[_FH_EXTRA_FIELD_LENGTH]) fname = fp.read(fheader[_FH_FILENAME_LENGTH]) if fname != data.orig_filename: - raise RuntimeError, \ + raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( data.orig_filename, fname) fp.seek(self.start_dir, 0) Modified: pypy/trunk/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/trunk/pypy/rpython/exceptiondata.py (original) +++ pypy/trunk/pypy/rpython/exceptiondata.py Mon Mar 29 21:35:09 2010 @@ -1,5 +1,6 @@ from pypy.rpython import rclass from pypy.annotation import model as annmodel +from pypy.rlib import rstackovf # the exceptions that can be implicitely raised by some operations @@ -19,6 +20,7 @@ UnicodeDecodeError: True, UnicodeEncodeError: True, NotImplementedError: True, + rstackovf._StackOverflow: True, } Modified: pypy/trunk/pypy/rpython/llinterp.py ============================================================================== --- pypy/trunk/pypy/rpython/llinterp.py (original) +++ pypy/trunk/pypy/rpython/llinterp.py Mon Mar 29 21:35:09 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic +from pypy.rlib import rstackovf import sys, os import math @@ -321,6 +322,18 @@ except LLException, e: if not (catch_exception and op is block.operations[-1]): raise + except RuntimeError, e: + rstackovf.check_stack_overflow(e) + # xxx fish fish fish for proper etype and evalue to use + rtyper = self.llinterpreter.typer + bk = rtyper.annotator.bookkeeper + classdef = bk.getuniqueclassdef(rstackovf._StackOverflow) + exdata = rtyper.getexceptiondata() + evalue = exdata.get_standard_ll_exc_instance(rtyper, classdef) + etype = exdata.fn_type_of_exc_inst(evalue) + e = LLException(etype, evalue) + if not (catch_exception and op is block.operations[-1]): + raise e # determine nextblock and/or return value if len(block.exits) == 0: Modified: pypy/trunk/pypy/translator/c/node.py ============================================================================== --- pypy/trunk/pypy/translator/c/node.py (original) +++ pypy/trunk/pypy/translator/c/node.py Mon Mar 29 21:35:09 2010 @@ -11,6 +11,7 @@ from pypy.translator.c.support import c_char_array_constant, barebonearray from pypy.translator.c.primitive import PrimitiveType, name_signed from pypy.rlib.rarithmetic import isinf, isnan +from pypy.rlib.rstackovf import _StackOverflow from pypy.translator.c import extfunc from pypy.translator.tool.cbuild import ExternalCompilationInfo from py.builtin import BaseException @@ -981,6 +982,8 @@ return 'PyExc_' + value.__name__ if value is py.code._AssertionError: return 'PyExc_AssertionError' + if value is _StackOverflow: + return 'PyExc_RuntimeError' raise Exception("don't know how to simply render py object: %r" % (value, )) Modified: pypy/trunk/pypy/translator/c/src/exception.h ============================================================================== --- pypy/trunk/pypy/translator/c/src/exception.h (original) +++ pypy/trunk/pypy/translator/c/src/exception.h Mon Mar 29 21:35:09 2010 @@ -104,6 +104,9 @@ /* workaround against the py lib's BuiltinAssertionError */ pycls = PyExc_AssertionError; } + else if (strcmp(clsname, "StackOverflow") == 0) { + pycls = PyExc_RuntimeError; + } else { pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); if (pycls == NULL || !PyExceptionClass_Check(pycls) || Modified: pypy/trunk/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/trunk/pypy/translator/exceptiontransform.py (original) +++ pypy/trunk/pypy/translator/exceptiontransform.py Mon Mar 29 21:35:09 2010 @@ -13,6 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib.debug import ll_assert +from pypy.rlib.rstackovf import _StackOverflow from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.tool.sourcetools import func_with_new_name @@ -60,8 +61,8 @@ exc_data, null_type, null_value = self.setup_excdata() rclass = translator.rtyper.type_system.rclass - (runtime_error_ll_exc_type, - runtime_error_ll_exc) = self.get_builtin_exception(RuntimeError) + (stackovf_ll_exc_type, + stackovf_ll_exc) = self.get_builtin_exception(_StackOverflow) (assertion_error_ll_exc_type, assertion_error_ll_exc) = self.get_builtin_exception(AssertionError) (n_i_error_ll_exc_type, @@ -114,8 +115,8 @@ exc_data.exc_type = rclass.ll_inst_type(evalue) exc_data.exc_value = evalue - def rpyexc_raise_runtime_error(): - rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) + def rpyexc_raise_stack_overflow(): + rpyexc_raise(stackovf_ll_exc_type, stackovf_ll_exc) self.rpyexc_occured_ptr = self.build_func( "RPyExceptionOccurred", @@ -151,9 +152,9 @@ lltype.Void, jitcallkind='rpyexc_raise') # for the JIT - self.rpyexc_raise_runtime_error_ptr = self.build_func( - "RPyRaiseRuntimeError", - self.noinline(rpyexc_raise_runtime_error), + self.rpyexc_raise_stack_overflow_ptr = self.build_func( + "RPyRaiseStackOverflow", + self.noinline(rpyexc_raise_stack_overflow), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -237,10 +238,10 @@ if block.operations[i].opname == 'stack_unwind': # if there are stack_unwind ops left, # the graph was not stackless-transformed - # so we need to raise a RuntimeError in any + # so we need to raise a StackOverflow in any # case block.operations[i].opname = "direct_call" - block.operations[i].args = [self.rpyexc_raise_runtime_error_ptr] + block.operations[i].args = [self.rpyexc_raise_stack_overflow_ptr] def replace_fetch_restore_operations(self, block): # the gctransformer will create these operations. It looks as if the Modified: pypy/trunk/pypy/translator/stackless/code.py ============================================================================== --- pypy/trunk/pypy/translator/stackless/code.py (original) +++ pypy/trunk/pypy/translator/stackless/code.py Mon Mar 29 21:35:09 2010 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.tool.sourcetools import func_with_new_name -from pypy.rlib import rarithmetic, objectmodel +from pypy.rlib import rarithmetic, objectmodel, rstackovf from pypy.translator.stackless import frame from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE, STORAGE_TYPES_AND_FIELDS @@ -382,7 +382,7 @@ # uncommon case: exceed the limit pending = pending.f_back pending.f_depth = depth - 1 - e = RuntimeError() + e = rstackovf._StackOverflow() if not pending: raise e global_state.exception = e From arigo at codespeak.net Mon Mar 29 21:35:33 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Mar 2010 21:35:33 +0200 (CEST) Subject: [pypy-svn] r73131 - pypy/branch/stackovf Message-ID: <20100329193533.AA039282B9D@codespeak.net> Author: arigo Date: Mon Mar 29 21:35:31 2010 New Revision: 73131 Removed: pypy/branch/stackovf/ Log: Merged branch. From getxsick at codespeak.net Mon Mar 29 21:57:05 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 21:57:05 +0200 (CEST) Subject: [pypy-svn] r73132 - pypy/trunk/lib-python Message-ID: <20100329195705.C2348282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 21:57:03 2010 New Revision: 73132 Modified: pypy/trunk/lib-python/conftest.py Log: add _locale module to test_locale.py Modified: pypy/trunk/lib-python/conftest.py ============================================================================== --- pypy/trunk/lib-python/conftest.py (original) +++ pypy/trunk/lib-python/conftest.py Mon Mar 29 21:57:03 2010 @@ -282,7 +282,7 @@ RegrTest('test_largefile.py'), RegrTest('test_linuxaudiodev.py', skip="unsupported extension module"), RegrTest('test_list.py', core=True), - RegrTest('test_locale.py'), + RegrTest('test_locale.py', usemodules="_locale"), RegrTest('test_logging.py', usemodules='thread'), RegrTest('test_long.py', core=True), RegrTest('test_long_future.py', core=True), From benjamin at codespeak.net Mon Mar 29 22:08:49 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 22:08:49 +0200 (CEST) Subject: [pypy-svn] r73133 - in pypy/branch/cleanup-objspace-init/pypy: interpreter objspace/std Message-ID: <20100329200849.0D85D282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 22:08:48 2010 New Revision: 73133 Modified: pypy/branch/cleanup-objspace-init/pypy/interpreter/baseobjspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: cleanup builtin module initialization Modified: pypy/branch/cleanup-objspace-init/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/interpreter/baseobjspace.py Mon Mar 29 22:08:48 2010 @@ -1,3 +1,5 @@ +import itertools +import pypy from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction from pypy.interpreter.error import OperationError, operationerrfmt @@ -405,7 +407,6 @@ if ('time2' in modules or 'rctime' in modules) and 'time' in modules: modules.remove('time') - import pypy if not self.config.objspace.nofaking: for modname in self.ALL_BUILTIN_MODULES: if not (os.path.exists( @@ -448,19 +449,18 @@ self.builtin_modules['__builtin__'] = self.wrap(w_builtin) self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) - bootstrap_modules = ['sys', 'imp', '__builtin__', 'exceptions'] - installed_builtin_modules = bootstrap_modules[:] + bootstrap_modules = set(('sys', 'imp', '__builtin__', 'exceptions')) + installed_builtin_modules = list(bootstrap_modules) - self.export_builtin_exceptions() + exception_types_w = self.export_builtin_exceptions() # initialize with "bootstrap types" from objspace (e.g. w_None) - for name, value in self.__dict__.items(): - if name.startswith('w_') and not name.endswith('Type'): - name = name[2:] - #print "setitem: space instance %-20s into builtins" % name - self.setitem(self.builtin.w_dict, self.wrap(name), value) + types_w = itertools.chain(self.get_builtin_types().iteritems(), + exception_types_w.iteritems()) + for name, w_type in types_w: + self.setitem(self.builtin.w_dict, self.wrap(name), w_type) - # install mixed and faked modules and set builtin_module_names on sys + # install mixed and faked modules for mixedname in self.get_builtinmodule_to_install(): if (mixedname not in bootstrap_modules and not mixedname.startswith('faked+')): @@ -478,17 +478,24 @@ self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'), w_builtin_module_names) + def get_builtin_types(self): + """Get a dictionary mapping the names of builtin types to the type + objects.""" + raise NotImplementedError + def export_builtin_exceptions(self): """NOT_RPYTHON""" w_dic = self.exceptions_module.getdict() - names_w = self.unpackiterable(self.call_function(self.getattr(w_dic, self.wrap("keys")))) - - for w_name in names_w: + w_keys = self.call_method(w_dic, "keys") + exc_types_w = {} + for w_name in self.unpackiterable(w_keys): name = self.str_w(w_name) if not name.startswith('__'): excname = name w_exc = self.getitem(w_dic, w_name) - setattr(self, "w_"+excname, w_exc) + exc_types_w[name] = w_exc + setattr(self, "w_" + excname, w_exc) + return exc_types_w def install_mixedmodule(self, mixedname, installed_builtin_modules): """NOT_RPYTHON""" Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 22:08:48 2010 @@ -74,9 +74,13 @@ self.w_Ellipsis = self.wrap(special.Ellipsis(self)) # types + self.builtin_types = {} for typedef in self.model.pythontypes: w_type = self.gettypeobject(typedef) + self.builtin_types[typedef.name] = w_type setattr(self, 'w_' + typedef.name, w_type) + self.builtin_types["NotImplemented"] = self.w_NotImplemented + self.builtin_types["Ellipsis"] = self.w_Ellipsis # exceptions & builtins self.make_builtins() @@ -90,6 +94,9 @@ if self.config.objspace.std.withtproxy: transparent.setup(self) + def get_builtin_types(self): + return self.builtin_types + def _setup_method_cache(self): SIZE = 1 << self.config.objspace.std.methodcachesizeexp self.method_cache_versions = [None] * SIZE From getxsick at codespeak.net Mon Mar 29 22:18:37 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Mon, 29 Mar 2010 22:18:37 +0200 (CEST) Subject: [pypy-svn] r73134 - pypy/build/ubuntu/trunk Message-ID: <20100329201837.8BCD7282B9D@codespeak.net> Author: getxsick Date: Mon Mar 29 22:18:36 2010 New Revision: 73134 Modified: pypy/build/ubuntu/trunk/autobuild.sh Log: use tee to store logs into the logfile but also print them on the screen. in this way cron can send them via email as well Modified: pypy/build/ubuntu/trunk/autobuild.sh ============================================================================== --- pypy/build/ubuntu/trunk/autobuild.sh (original) +++ pypy/build/ubuntu/trunk/autobuild.sh Mon Mar 29 22:18:36 2010 @@ -51,4 +51,4 @@ echo "`date -R` : Packages built and sent successfully." | \ mail -s "[pypy-autobuild] status" $DEBEMAIL echo "--- Finish the new build at `date -R`" -) >>$LOGFILE 2>&1 +) 2>&1 | tee --append $LOGFILE From benjamin at codespeak.net Mon Mar 29 22:57:31 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 22:57:31 +0200 (CEST) Subject: [pypy-svn] r73135 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329205731.7330E282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 22:57:30 2010 New Revision: 73135 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py Log: kill hacks and old code Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py Mon Mar 29 22:57:30 2010 @@ -4,20 +4,20 @@ 'and': 'and_', 'or': 'or_', } - + def register_all(module_dict, *alt_ns): - """register implementations for multimethods. + """register implementations for multimethods. By default a (name, object) pair of the given module dictionary is registered on the multimethod 'name' of StdObjSpace. If the name doesn't exist then the alternative namespace is tried - for registration. + for registration. """ namespaces = list(alt_ns) + [model.MM] for name, obj in module_dict.items(): - if name.startswith('app_'): - print "%s: direct app definitions deprecated" % name + if name.startswith('app_'): + print "%s: direct app definitions deprecated" % name if name.find('__')<1 or name.startswith('app_'): continue funcname, sig = name.split('__') @@ -39,13 +39,6 @@ "no W_%s or W_%sObject for the definition of %s" % ( i, i, name) l.append(icls) - - #XXX trying to be too clever at the moment for userobject.SpecialMethod - #if len(l) != obj.func_code.co_argcount-1: - # raise ValueError, \ - # "function name %s doesn't specify exactly %d arguments" % ( - # repr(name), obj.func_code.co_argcount-1) - funcname = _name_mappings.get(funcname, funcname) func = hack_func_by_name(funcname, namespaces) @@ -62,17 +55,6 @@ else: if hasattr(ns, funcname): return getattr(ns, funcname) - #import typetype - #try: - # return getattr(typetype.W_TypeType, funcname) - #except AttributeError: - # pass # catches not only the getattr() but the typetype.W_TypeType - # # in case it is not fully imported yet :-(((( - from pypy.objspace.std import objecttype - try: - return getattr(objecttype, funcname) - except AttributeError: - pass raise NameError, ("trying hard but not finding a multimethod named %s" % funcname) @@ -128,9 +110,4 @@ ' registration of comparison functions' ' only work when there is a single method for' ' the operation.') - #print 'adding %s <<<%s>>> %s as %s(%s)' % ( - # t1, op2, t2, - # correspondance.func_name, functions[0].func_name) - mirrorfunc.register( - correspondance(functions[0]), - *types) + mirrorfunc.register(correspondance(functions[0]), *types) From benjamin at codespeak.net Mon Mar 29 23:09:48 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:09:48 +0200 (CEST) Subject: [pypy-svn] r73136 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329210948.6B167282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:09:46 2010 New Revision: 73136 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py Log: cleanup ws Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py Mon Mar 29 23:09:46 2010 @@ -176,11 +176,11 @@ ] self.typeorder[longobject.W_LongObject] += [ (floatobject.W_FloatObject, floatobject.delegate_Long2Float), - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Long2Complex), ] self.typeorder[floatobject.W_FloatObject] += [ - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] self.typeorder[setobject.W_SetObject] += [ @@ -318,13 +318,13 @@ break else: self.name = operatorsymbol - + if extras.get('general__args__', False): self.argnames_after = ['__args__'] if extras.get('w_varargs', False): self.argnames_after = ['w_args'] if extras.get('varargs_w', False): - self.argnames_after = ['args_w'] + self.argnames_after = ['args_w'] self.argnames_after += extras.get('extra_args', []) def install_not_sliced(self, typeorder, baked_perform_call=True): From benjamin at codespeak.net Mon Mar 29 23:14:06 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:14:06 +0200 (CEST) Subject: [pypy-svn] r73137 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329211406.D984F282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:14:05 2010 New Revision: 73137 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py Log: only add compliment comparison operators once Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/model.py Mon Mar 29 23:14:05 2010 @@ -270,6 +270,60 @@ self._typeorder_with_empty_usersubcls = result return self._typeorder_with_empty_usersubcls +def _op_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_1, w_2)) + return op + +def _op_swapped(function): + def op(space, w_1, w_2): + return function(space, w_2, w_1) + return op + +def _op_swapped_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_2, w_1)) + return op + +OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] +OP_CORRESPONDANCES = [ + ('eq', 'ne', _op_negated), + ('lt', 'gt', _op_swapped), + ('le', 'ge', _op_swapped), + ('lt', 'ge', _op_negated), + ('le', 'gt', _op_negated), + ('lt', 'le', _op_swapped_negated), + ('gt', 'ge', _op_swapped_negated), + ] +for op1, op2, value in OP_CORRESPONDANCES[:]: + i = OP_CORRESPONDANCES.index((op1, op2, value)) + OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) + +def add_extra_comparisons(): + """ + Add the missing comparison operators if they were not explicitly + defined: eq <-> ne and lt <-> le <-> gt <-> ge. + We try to add them in the order defined by the OP_CORRESPONDANCES + table, thus favouring swapping the arguments over negating the result. + """ + originalentries = {} + for op in OPERATORS: + originalentries[op] = getattr(MM, op).signatures() + + for op1, op2, correspondance in OP_CORRESPONDANCES: + mirrorfunc = getattr(MM, op2) + for types in originalentries[op1]: + t1, t2 = types + if t1 is t2: + if not mirrorfunc.has_signature(types): + functions = getattr(MM, op1).getfunctions(types) + assert len(functions) == 1, ('Automatic' + ' registration of comparison functions' + ' only work when there is a single method for' + ' the operation.') + mirrorfunc.register(correspondance(functions[0]), *types) + + # ____________________________________________________________ W_ANY = W_Root Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:14:05 2010 @@ -108,6 +108,7 @@ def _install_multimethods(self): """Install all the MultiMethods into the space instance.""" + model.add_extra_comparisons() for name, mm in model.MM.__dict__.items(): if not isinstance(mm, model.StdObjSpaceMultiMethod): continue Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/register_all.py Mon Mar 29 23:14:05 2010 @@ -44,8 +44,6 @@ func = hack_func_by_name(funcname, namespaces) func.register(obj, *l) - add_extra_comparisons() - def hack_func_by_name(funcname, namespaces): for ns in namespaces: @@ -57,57 +55,3 @@ return getattr(ns, funcname) raise NameError, ("trying hard but not finding a multimethod named %s" % funcname) - - -def op_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_1, w_2)) - return op - -def op_swapped(function): - def op(space, w_1, w_2): - return function(space, w_2, w_1) - return op - -def op_swapped_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_2, w_1)) - return op - -OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] -OP_CORRESPONDANCES = [ - ('eq', 'ne', op_negated), - ('lt', 'gt', op_swapped), - ('le', 'ge', op_swapped), - ('lt', 'ge', op_negated), - ('le', 'gt', op_negated), - ('lt', 'le', op_swapped_negated), - ('gt', 'ge', op_swapped_negated), - ] -for op1, op2, value in OP_CORRESPONDANCES[:]: - i = OP_CORRESPONDANCES.index((op1, op2, value)) - OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) - -def add_extra_comparisons(): - """ - Add the missing comparison operators if they were not explicitly - defined: eq <-> ne and lt <-> le <-> gt <-> ge. - We try to add them in the order defined by the OP_CORRESPONDANCES - table, thus favouring swapping the arguments over negating the result. - """ - originalentries = {} - for op in OPERATORS: - originalentries[op] = getattr(model.MM, op).signatures() - - for op1, op2, correspondance in OP_CORRESPONDANCES: - mirrorfunc = getattr(model.MM, op2) - for types in originalentries[op1]: - t1, t2 = types - if t1 is t2: - if not mirrorfunc.has_signature(types): - functions = getattr(model.MM, op1).getfunctions(types) - assert len(functions) == 1, ('Automatic' - ' registration of comparison functions' - ' only work when there is a single method for' - ' the operation.') - mirrorfunc.register(correspondance(functions[0]), *types) From benjamin at codespeak.net Mon Mar 29 23:47:25 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:47:25 +0200 (CEST) Subject: [pypy-svn] r73138 - in pypy/branch/cleanup-objspace-init/pypy/objspace/std: . test Message-ID: <20100329214725.B3A01282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:47:23 2010 New Revision: 73138 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/booltype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxytype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/floattype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/inttype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/itertype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/listtype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/longtype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/nonetype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/slicetype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringtype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/typetype.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodetype.py Log: cleanup type definition files * remove stdtypedef.newmethod * import things from their actual location * some whitespace cleanup Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/booltype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/booltype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/booltype.py Mon Mar 29 23:47:23 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.inttype import int_typedef def descr__new__(space, w_booltype, w_obj=None): @@ -16,6 +17,6 @@ Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) bool_typedef.acceptable_as_base_class = False Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/complextype.py Mon Mar 29 23:47:23 2010 @@ -1,9 +1,9 @@ -from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import interp_string_to_float, ParseStringError from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef, newmethod +from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod # ERRORCODES @@ -36,7 +36,7 @@ # extract first number realstart = i pc = s[i] - while i < slen and s[i] != ' ': + while i < slen and s[i] != ' ': if s[i] in ('+','-') and pc not in ('e','E') and i != realstart: break pc = s[i] @@ -136,8 +136,9 @@ except ParseStringError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) else: - #check for overflow - if abs(realval) == OVERFLOWED_FLOAT or abs(imagval) == OVERFLOWED_FLOAT: + # check for overflow + if (abs(realval) == OVERFLOWED_FLOAT or + abs(imagval) == OVERFLOWED_FLOAT): raise OperationError(space.w_ValueError,space.wrap( "complex() literal too large to convert")) @@ -156,8 +157,8 @@ w_real = space.call_function(w_method) # __complex__() could return a string, which space.float() # could accept below... Let's catch this case. - if space.is_true(space.isinstance(w_imag, space.w_str)) or \ - space.is_true(space.isinstance(w_imag, space.w_unicode)): + if (space.is_true(space.isinstance(w_imag, space.w_str)) or + space.is_true(space.isinstance(w_imag, space.w_unicode))): raise OperationError(space.w_TypeError, space.wrap("__complex__() cannot return" " a string")) @@ -205,19 +206,19 @@ space.wrap("descriptor is for 'complex'")) return space.newfloat(getattr(w_obj, name)) return GetSetProperty(fget) - + def descr___getnewargs__(space, w_self): from pypy.objspace.std.complexobject import W_ComplexObject assert isinstance(w_self, W_ComplexObject) - return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) - + return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) + complex_typedef = StdTypeDef("complex", __doc__ = """complex(real[, imag]) -> complex number - + Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""", - __new__ = newmethod(descr__new__), - __getnewargs__ = newmethod(descr___getnewargs__), + __new__ = gateway.interp2app(descr__new__), + __getnewargs__ = gateway.interp2app(descr___getnewargs__), real = complexwprop('realval'), imag = complexwprop('imagval'), ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxytype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxytype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/dictproxytype.py Mon Mar 29 23:47:23 2010 @@ -1,5 +1,7 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.interpreter.typedef import GetSetProperty from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/dicttype.py Mon Mar 29 23:47:23 2010 @@ -1,7 +1,8 @@ from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -176,8 +177,10 @@ d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)''', - __new__ = newmethod(descr__new__, - unwrap_spec=[gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec= + [gateway.ObjSpace, + gateway.W_Root,gateway.Arguments]), __hash__ = no_hash_descr, fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True), ) @@ -200,18 +203,16 @@ XXX to do: remove this __reduce__ method and do a registration with copy_reg, instead. """ - from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('dictiter_surrogate_new') w_typeobj = space.gettypeobject(dictiter_typedef) - - from pypy.interpreter.mixedmodule import MixedModule + raise OperationError( space.w_RuntimeError, space.wrap("cannot pickle dictiters with multidicts")) # XXXXXX get that working again - + # we cannot call __init__ since we don't have the original dict if isinstance(w_self, W_DictIter_Keys): w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj) @@ -237,7 +238,7 @@ w_res ] w_ret = space.newtuple([new_inst, space.newtuple(tup)]) - return w_ret + return w_ret # ____________________________________________________________ Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floattype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/floattype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/floattype.py Mon Mar 29 23:47:23 2010 @@ -1,5 +1,6 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.strutil import string_to_float, ParseStringError from pypy.objspace.std.strutil import interp_string_to_float @@ -48,5 +49,5 @@ __doc__ = '''float(x) -> floating point number Convert a string or number to a floating point number, if possible.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/frozensettype.py Mon Mar 29 23:47:23 2010 @@ -1,9 +1,8 @@ +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped -from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM + frozenset_copy = SMM('copy', 1, doc='Return a shallow copy of a set.') @@ -37,7 +36,8 @@ register_all(vars(), globals()) -def descr__frozenset__new__(space, w_frozensettype, w_iterable=NoneNotWrapped): +def descr__frozenset__new__(space, w_frozensettype, + w_iterable=gateway.NoneNotWrapped): from pypy.objspace.std.setobject import W_FrozensetObject from pypy.objspace.std.setobject import _is_frozenset_exact if (space.is_w(w_frozensettype, space.w_frozenset) and @@ -52,7 +52,7 @@ __doc__ = """frozenset(iterable) --> frozenset object Build an immutable unordered collection.""", - __new__ = newmethod(descr__frozenset__new__), + __new__ = gateway.interp2app(descr__frozenset__new__), ) frozenset_typedef.registermethods(globals()) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/inttype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/inttype.py Mon Mar 29 23:47:23 2010 @@ -1,7 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_int, string_to_w_long, ParseStringError, ParseStringOverflowError +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import (string_to_int, string_to_w_long, + ParseStringError, + ParseStringOverflowError) from pypy.rlib.rarithmetic import r_uint from pypy.rlib.objectmodel import instantiate @@ -47,8 +49,8 @@ except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) - -def descr__new__(space, w_inttype, w_x=0, w_base=NoneNotWrapped): + +def descr__new__(space, w_inttype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.intobject import W_IntObject w_longval = None w_value = w_x # 'x' is the keyword argument name in CPython @@ -64,7 +66,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) elif space.is_true(space.isinstance(w_value, space.w_unicode)): if space.config.objspace.std.withropeunicode: from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w @@ -77,7 +79,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) else: # otherwise, use the __int__() method w_obj = space.int(w_value) @@ -116,13 +118,13 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser, base) + w_longval = retry_to_w_long(space, e.parser, base) if w_longval is not None: if not space.is_w(w_inttype, space.w_int): raise OperationError(space.w_OverflowError, space.wrap( - "long int too large to convert to int")) + "long int too large to convert to int")) return w_longval elif space.is_w(w_inttype, space.w_int): # common case @@ -143,5 +145,5 @@ the optional base. It is an error to supply a base when converting a non-string. If the argument is outside the integer range a long object will be returned instead.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/itertype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/itertype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/itertype.py Mon Mar 29 23:47:23 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/listtype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/listtype.py Mon Mar 29 23:47:23 2010 @@ -1,6 +1,6 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from sys import maxint @@ -24,7 +24,8 @@ ' occurrences of value') list_reverse = SMM('reverse',1, doc='L.reverse() -- reverse *IN PLACE*') -list_sort = SMM('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse'], +list_sort = SMM('sort', 4, defaults=(None, None, False), + argnames=['cmp', 'key', 'reverse'], doc='L.sort(cmp=None, key=None, reverse=False) -- stable' ' sort *IN PLACE*;\ncmp(x, y) -> -1, 0, 1') list_reversed = SMM('__reversed__', 1, @@ -50,9 +51,9 @@ list_typedef = StdTypeDef("list", __doc__ = '''list() -> new list list(sequence) -> new list initialized from sequence's items''', - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) list_typedef.registermethods(globals()) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/longtype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/longtype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/longtype.py Mon Mar 29 23:47:23 2010 @@ -1,9 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_w_long, ParseStringError from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import string_to_w_long, ParseStringError -def descr__new__(space, w_longtype, w_x=0, w_base=NoneNotWrapped): +def descr__new__(space, w_longtype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.longobject import W_LongObject w_value = w_x # 'x' is the keyword argument name in CPython if w_base is None: @@ -75,5 +75,5 @@ string representation of a floating point number!) When converting a string, use the optional base. It is an error to supply a base when converting a non-string.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/nonetype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/nonetype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/nonetype.py Mon Mar 29 23:47:23 2010 @@ -1,4 +1,4 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objecttype.py Mon Mar 29 23:47:23 2010 @@ -1,9 +1,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.interpreter.typedef import GetSetProperty -from pypy.objspace.descroperation import Object +from pypy.interpreter.typedef import GetSetProperty, default_identity_hash from pypy.interpreter import gateway -from pypy.interpreter.typedef import default_identity_hash -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod +from pypy.objspace.descroperation import Object +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr from pypy.objspace.std.register_all import register_all @@ -171,8 +170,8 @@ __repr__ = gateway.interp2app(descr__repr__), __class__ = GetSetProperty(descr__class__, descr_set___class__), __doc__ = '''The most base type''', - __new__ = newmethod(descr__new__, - unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), __hash__ = gateway.interp2app(default_identity_hash), __reduce_ex__ = gateway.interp2app(descr__reduce_ex__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,int]), Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/settype.py Mon Mar 29 23:47:23 2010 @@ -1,8 +1,7 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter import gateway from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod, no_hash_descr -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr, SMM from pypy.interpreter import gateway set_add = SMM('add', 2, @@ -77,9 +76,9 @@ __doc__ = """set(iterable) --> set object Build an unordered collection.""", - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/slicetype.py Mon Mar 29 23:47:23 2010 @@ -1,6 +1,6 @@ -import sys -from pypy.interpreter import baseobjspace -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import baseobjspace, gateway +from pypy.interpreter.typedef import GetSetProperty +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -88,7 +88,7 @@ __doc__ = '''slice([start,] stop[, step]) Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __hash__ = no_hash_descr, start = slicewprop('w_start'), stop = slicewprop('w_stop'), Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/stdtypedef.py Mon Mar 29 23:47:23 2010 @@ -10,9 +10,7 @@ from pypy.rlib import jit from pypy.tool.sourcetools import compile2 -__all__ = ['StdTypeDef', 'newmethod', 'gateway', - 'GetSetProperty', 'Member', - 'SMM', 'descr_get_dict', 'no_hash_descr'] +__all__ = ['StdTypeDef', 'SMM', 'no_hash_descr'] SMM = StdObjSpaceMultiMethod @@ -43,11 +41,6 @@ std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict) std_dict_descr.name = '__dict__' -def newmethod(descr_new, unwrap_spec=None): - "NOT_RPYTHON: initialization-time only." - # this is turned into a static method by the constructor of W_TypeObject. - return gateway.interp2app(descr_new, unwrap_spec=unwrap_spec) - # ____________________________________________________________ # # All the code below fishes from the multimethod registration tables Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/stringtype.py Mon Mar 29 23:47:23 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.basestringtype import basestring_typedef from sys import maxint @@ -42,7 +43,7 @@ def sliced(space, s, start, stop, orig_obj): assert start >= 0 - assert stop >= 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 @@ -294,7 +295,7 @@ # ____________________________________________________________ str_typedef = StdTypeDef("str", basestring_typedef, - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __doc__ = '''str(object) -> string Return a nice string representation of the object. @@ -326,4 +327,3 @@ if u_self[start+i] != prefix[i]: return False return True - Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/test/test_typeobject.py Mon Mar 29 23:47:23 2010 @@ -1,5 +1,5 @@ from pypy.objspace.std.model import W_Object -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.conftest import gettestobjspace from pypy.objspace.std.typeobject import W_TypeObject @@ -15,7 +15,7 @@ def descr__new__(space, w_subtype): return space.allocate_instance(W_Stuff, w_subtype) W_Stuff.typedef = StdTypeDef("stuff", - __new__ = newmethod(descr__new__)) + __new__ = interp2app(descr__new__)) W_Stuff.typedef.acceptable_as_base_class = False w_stufftype = space.gettypeobject(W_Stuff.typedef) space.appexec([w_stufftype], """(stufftype): Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py Mon Mar 29 23:47:23 2010 @@ -1,11 +1,11 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef def wraptuple(space, list_w): from pypy.objspace.std.tupleobject import W_TupleObject return W_TupleObject(list_w) -def descr__new__(space, w_tupletype, w_sequence=NoneNotWrapped): +def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped): from pypy.objspace.std.tupleobject import W_TupleObject if w_sequence is None: tuple_w = [] @@ -25,5 +25,5 @@ tuple(sequence) -> tuple initialized from sequence's items If the argument is a tuple, the return value is the same object.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/typetype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/typetype.py Mon Mar 29 23:47:23 2010 @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments -from pypy.interpreter.typedef import weakref_descr -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, + weakref_descr) +from pypy.objspace.std.stdtypedef import StdTypeDef def descr__new__(space, w_typetype, w_name, w_bases, w_dict): "This is used to create user-defined classes only." @@ -10,7 +11,7 @@ # XXX check types w_typetype = _precheck_for_new(space, w_typetype) - + bases_w = space.fixedview(w_bases) w_winner = w_typetype @@ -34,7 +35,7 @@ if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))): return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict) w_typetype = w_winner - + name = space.str_w(w_name) assert isinstance(name, str) dict_w = {} @@ -187,7 +188,7 @@ return space.get(w_result, space.w_None, w_type) def descr__flags(space, w_type): - w_type = _check(space, w_type) + w_type = _check(space, w_type) return space.wrap(w_type.__flags__) def descr_get__module(space, w_type): @@ -195,9 +196,9 @@ return w_type.get_module() def descr_set__module(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__module__", w_type.name) w_type.mutated() @@ -211,7 +212,7 @@ # ____________________________________________________________ type_typedef = StdTypeDef("type", - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __name__ = GetSetProperty(descr_get__name__, descr_set__name__), __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__), __base__ = GetSetProperty(descr__base), Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodetype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/unicodetype.py Mon Mar 29 23:47:23 2010 @@ -1,8 +1,8 @@ +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -286,7 +286,7 @@ # ____________________________________________________________ unicode_typedef = StdTypeDef("unicode", basestring_typedef, - __new__ = newmethod(descr_new_), + __new__ = gateway.interp2app(descr_new_), __doc__ = '''unicode(string [, encoding[, errors]]) -> object Create a new Unicode object from the given encoded string. From benjamin at codespeak.net Mon Mar 29 23:48:07 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:48:07 +0200 (CEST) Subject: [pypy-svn] r73139 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329214807.6E9B2282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:48:05 2010 New Revision: 73139 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: simplify Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:48:05 2010 @@ -55,10 +55,10 @@ self.TupleObjectCls = W_TupleObject - if not self.config.objspace.std.withrope: - self.StringObjectCls = W_StringObject - else: + if self.config.objspace.std.withrope: self.StringObjectCls = W_RopeObject + else: + self.StringObjectCls = W_StringObject assert self.StringObjectCls in self.model.typeorder self._install_multimethods() From benjamin at codespeak.net Mon Mar 29 23:49:14 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:49:14 +0200 (CEST) Subject: [pypy-svn] r73140 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329214914.30266282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:49:12 2010 New Revision: 73140 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: this attribute isn't used Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:49:12 2010 @@ -53,14 +53,6 @@ # store the dict class on the space to access it in various places self.DictObjectCls = W_DictMultiObject - self.TupleObjectCls = W_TupleObject - - if self.config.objspace.std.withrope: - self.StringObjectCls = W_RopeObject - else: - self.StringObjectCls = W_StringObject - assert self.StringObjectCls in self.model.typeorder - self._install_multimethods() if self.config.objspace.std.withmethodcache: From benjamin at codespeak.net Mon Mar 29 23:51:18 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:51:18 +0200 (CEST) Subject: [pypy-svn] r73141 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329215118.A629D282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:51:17 2010 New Revision: 73141 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: W_DictMultiObject is always the dict class Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:51:17 2010 @@ -50,9 +50,6 @@ self.FrameClass = frame.build_frame(self) - # store the dict class on the space to access it in various places - self.DictObjectCls = W_DictMultiObject - self._install_multimethods() if self.config.objspace.std.withmethodcache: @@ -462,21 +459,21 @@ def finditem_str(self, w_obj, key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem_str(key) return ObjSpace.finditem_str(self, w_obj, key) def finditem(self, w_obj, w_key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem(w_key) return ObjSpace.finditem(self, w_obj, w_key) def set_str_keyed_item(self, w_obj, key, w_value, shadows_type=True): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): w_obj.set_str_keyed_item(key, w_value, shadows_type) else: From benjamin at codespeak.net Mon Mar 29 23:52:59 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:52:59 +0200 (CEST) Subject: [pypy-svn] r73142 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329215259.3D928282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:52:57 2010 New Revision: 73142 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Log: restore StringObjectCls for tests Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:52:57 2010 @@ -50,6 +50,11 @@ self.FrameClass = frame.build_frame(self) + if self.config.objspace.std.withrope: + self.StringObjectCls = W_RopeObject + else: + self.StringObjectCls = W_StringObject + self._install_multimethods() if self.config.objspace.std.withmethodcache: From benjamin at codespeak.net Mon Mar 29 23:58:13 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Mon, 29 Mar 2010 23:58:13 +0200 (CEST) Subject: [pypy-svn] r73143 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329215813.EC8F7282B9D@codespeak.net> Author: benjamin Date: Mon Mar 29 23:58:12 2010 New Revision: 73143 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py Log: remove wraptuple Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/objspace.py Mon Mar 29 23:58:12 2010 @@ -35,7 +35,6 @@ # types from pypy.objspace.std.inttype import wrapint from pypy.objspace.std.stringtype import wrapstr -from pypy.objspace.std.tupletype import wraptuple from pypy.objspace.std.unicodetype import wrapunicode @@ -280,7 +279,7 @@ def newtuple(self, list_w): assert isinstance(list_w, list) make_sure_not_resized(list_w) - return wraptuple(self, list_w) + return W_TupleObject(list_w) def newlist(self, list_w): return W_ListObject(list_w) Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupletype.py Mon Mar 29 23:58:12 2010 @@ -1,10 +1,6 @@ from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import StdTypeDef -def wraptuple(space, list_w): - from pypy.objspace.std.tupleobject import W_TupleObject - return W_TupleObject(list_w) - def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped): from pypy.objspace.std.tupleobject import W_TupleObject if w_sequence is None: @@ -14,8 +10,8 @@ return w_sequence else: tuple_w = space.fixedview(w_sequence) - w_obj = space.allocate_instance(space.TupleObjectCls, w_tupletype) - space.TupleObjectCls.__init__(w_obj, tuple_w) + w_obj = space.allocate_instance(W_TupleObject, w_tupletype) + W_TupleObject.__init__(w_obj, tuple_w) return w_obj # ____________________________________________________________ From benjamin at codespeak.net Tue Mar 30 00:03:06 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:03:06 +0200 (CEST) Subject: [pypy-svn] r73144 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329220306.1D654282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:03:04 2010 New Revision: 73144 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py Log: add FailedToImplementImportArgs import Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/floatobject.py Tue Mar 30 00:03:04 2010 @@ -2,6 +2,7 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError from pypy.objspace.std import model +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all from pypy.objspace.std.noneobject import W_NoneObject @@ -15,7 +16,7 @@ from pypy.objspace.std.intobject import W_IntObject class W_FloatObject(W_Object): - """This is a reimplementation of the CPython "PyFloatObject" + """This is a reimplementation of the CPython "PyFloatObject" it is assumed that the constructor takes a real Python float as an argument""" from pypy.objspace.std.floattype import float_typedef as typedef From benjamin at codespeak.net Tue Mar 30 00:07:56 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:07:56 +0200 (CEST) Subject: [pypy-svn] r73145 - pypy/branch/cleanup-objspace-init/pypy/objspace/std Message-ID: <20100329220756.0CD85282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:07:55 2010 New Revision: 73145 Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py Log: add FailedToImplement import Modified: pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/cleanup-objspace-init/pypy/objspace/std/tupleobject.py Tue Mar 30 00:07:55 2010 @@ -2,6 +2,7 @@ from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import intmask from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway From benjamin at codespeak.net Tue Mar 30 00:37:03 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:37:03 +0200 (CEST) Subject: [pypy-svn] r73147 - in pypy/trunk: . dotviewer lib-python pypy pypy/interpreter pypy/jit/backend/cli/test pypy/jit/backend/llvm/test pypy/jit/backend/x86/test pypy/jit/metainterp pypy/module/exceptions pypy/objspace/std pypy/objspace/std/test pypy/rlib/test pypy/translator/c/test Message-ID: <20100329223703.CBD46282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:36:58 2010 New Revision: 73147 Modified: pypy/trunk/ (props changed) pypy/trunk/dotviewer/ (props changed) pypy/trunk/lib-python/ (props changed) pypy/trunk/pypy/ (props changed) pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/jit/backend/cli/test/conftest.py (props changed) pypy/trunk/pypy/jit/backend/llvm/test/conftest.py (props changed) pypy/trunk/pypy/jit/backend/x86/test/test_gc_integration.py (props changed) pypy/trunk/pypy/jit/metainterp/logger.py (props changed) pypy/trunk/pypy/module/exceptions/ (props changed) pypy/trunk/pypy/objspace/std/__init__.py pypy/trunk/pypy/objspace/std/boolobject.py pypy/trunk/pypy/objspace/std/booltype.py pypy/trunk/pypy/objspace/std/complexobject.py pypy/trunk/pypy/objspace/std/complextype.py pypy/trunk/pypy/objspace/std/default.py pypy/trunk/pypy/objspace/std/dictmultiobject.py pypy/trunk/pypy/objspace/std/dictproxyobject.py pypy/trunk/pypy/objspace/std/dictproxytype.py pypy/trunk/pypy/objspace/std/dicttype.py pypy/trunk/pypy/objspace/std/floatobject.py pypy/trunk/pypy/objspace/std/floattype.py pypy/trunk/pypy/objspace/std/frozensettype.py pypy/trunk/pypy/objspace/std/intobject.py pypy/trunk/pypy/objspace/std/inttype.py pypy/trunk/pypy/objspace/std/iterobject.py pypy/trunk/pypy/objspace/std/itertype.py pypy/trunk/pypy/objspace/std/listobject.py pypy/trunk/pypy/objspace/std/listtype.py pypy/trunk/pypy/objspace/std/longobject.py pypy/trunk/pypy/objspace/std/longtype.py pypy/trunk/pypy/objspace/std/marshal_impl.py pypy/trunk/pypy/objspace/std/model.py pypy/trunk/pypy/objspace/std/noneobject.py pypy/trunk/pypy/objspace/std/nonetype.py pypy/trunk/pypy/objspace/std/objectobject.py pypy/trunk/pypy/objspace/std/objecttype.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/proxyobject.py pypy/trunk/pypy/objspace/std/rangeobject.py pypy/trunk/pypy/objspace/std/register_all.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/settype.py pypy/trunk/pypy/objspace/std/sliceobject.py pypy/trunk/pypy/objspace/std/slicetype.py pypy/trunk/pypy/objspace/std/smallintobject.py pypy/trunk/pypy/objspace/std/stdtypedef.py pypy/trunk/pypy/objspace/std/stringobject.py pypy/trunk/pypy/objspace/std/stringtype.py pypy/trunk/pypy/objspace/std/strjoinobject.py pypy/trunk/pypy/objspace/std/strsliceobject.py pypy/trunk/pypy/objspace/std/test/test_complexobject.py pypy/trunk/pypy/objspace/std/test/test_floatobject.py pypy/trunk/pypy/objspace/std/test/test_intobject.py pypy/trunk/pypy/objspace/std/test/test_longobject.py pypy/trunk/pypy/objspace/std/test/test_setobject.py (props changed) pypy/trunk/pypy/objspace/std/test/test_smallintobject.py pypy/trunk/pypy/objspace/std/test/test_typeobject.py pypy/trunk/pypy/objspace/std/transparent.py pypy/trunk/pypy/objspace/std/tupleobject.py pypy/trunk/pypy/objspace/std/tupletype.py pypy/trunk/pypy/objspace/std/typeobject.py pypy/trunk/pypy/objspace/std/typetype.py pypy/trunk/pypy/objspace/std/unicodeobject.py pypy/trunk/pypy/objspace/std/unicodetype.py pypy/trunk/pypy/rlib/test/test_rcoroutine.py (props changed) pypy/trunk/pypy/translator/c/test/test_refcount.py (props changed) Log: merge cleanup-obspace-init, in which objspace initialization becomes pretty Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Mar 30 00:36:58 2010 @@ -1,3 +1,5 @@ +import itertools +import pypy from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction from pypy.interpreter.error import OperationError, operationerrfmt @@ -405,7 +407,6 @@ if ('time2' in modules or 'rctime' in modules) and 'time' in modules: modules.remove('time') - import pypy if not self.config.objspace.nofaking: for modname in self.ALL_BUILTIN_MODULES: if not (os.path.exists( @@ -448,19 +449,18 @@ self.builtin_modules['__builtin__'] = self.wrap(w_builtin) self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) - bootstrap_modules = ['sys', 'imp', '__builtin__', 'exceptions'] - installed_builtin_modules = bootstrap_modules[:] + bootstrap_modules = set(('sys', 'imp', '__builtin__', 'exceptions')) + installed_builtin_modules = list(bootstrap_modules) - self.export_builtin_exceptions() + exception_types_w = self.export_builtin_exceptions() # initialize with "bootstrap types" from objspace (e.g. w_None) - for name, value in self.__dict__.items(): - if name.startswith('w_') and not name.endswith('Type'): - name = name[2:] - #print "setitem: space instance %-20s into builtins" % name - self.setitem(self.builtin.w_dict, self.wrap(name), value) + types_w = itertools.chain(self.get_builtin_types().iteritems(), + exception_types_w.iteritems()) + for name, w_type in types_w: + self.setitem(self.builtin.w_dict, self.wrap(name), w_type) - # install mixed and faked modules and set builtin_module_names on sys + # install mixed and faked modules for mixedname in self.get_builtinmodule_to_install(): if (mixedname not in bootstrap_modules and not mixedname.startswith('faked+')): @@ -478,17 +478,24 @@ self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'), w_builtin_module_names) + def get_builtin_types(self): + """Get a dictionary mapping the names of builtin types to the type + objects.""" + raise NotImplementedError + def export_builtin_exceptions(self): """NOT_RPYTHON""" w_dic = self.exceptions_module.getdict() - names_w = self.unpackiterable(self.call_function(self.getattr(w_dic, self.wrap("keys")))) - - for w_name in names_w: + w_keys = self.call_method(w_dic, "keys") + exc_types_w = {} + for w_name in self.unpackiterable(w_keys): name = self.str_w(w_name) if not name.startswith('__'): excname = name w_exc = self.getitem(w_dic, w_name) - setattr(self, "w_"+excname, w_exc) + exc_types_w[name] = w_exc + setattr(self, "w_" + excname, w_exc) + return exc_types_w def install_mixedmodule(self, mixedname, installed_builtin_modules): """NOT_RPYTHON""" Modified: pypy/trunk/pypy/objspace/std/__init__.py ============================================================================== --- pypy/trunk/pypy/objspace/std/__init__.py (original) +++ pypy/trunk/pypy/objspace/std/__init__.py Tue Mar 30 00:36:58 2010 @@ -1,2 +1,2 @@ -from objspace import StdObjSpace +from pypy.objspace.std.objspace import StdObjSpace Space = StdObjSpace Modified: pypy/trunk/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/boolobject.py (original) +++ pypy/trunk/pypy/objspace/std/boolobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.intobject import W_IntObject Modified: pypy/trunk/pypy/objspace/std/booltype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/booltype.py (original) +++ pypy/trunk/pypy/objspace/std/booltype.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.inttype import int_typedef def descr__new__(space, w_booltype, w_obj=None): @@ -16,6 +17,6 @@ Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) bool_typedef.acceptable_as_base_class = False Modified: pypy/trunk/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/complexobject.py (original) +++ pypy/trunk/pypy/objspace/std/complexobject.py Tue Mar 30 00:36:58 2010 @@ -1,6 +1,7 @@ from pypy.interpreter import gateway -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.floatobject import W_FloatObject, _hash_float import math Modified: pypy/trunk/pypy/objspace/std/complextype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/complextype.py (original) +++ pypy/trunk/pypy/objspace/std/complextype.py Tue Mar 30 00:36:58 2010 @@ -1,9 +1,9 @@ -from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import interp_string_to_float, ParseStringError -from pypy.objspace.std.objspace import register_all from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef, newmethod +from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod # ERRORCODES @@ -36,7 +36,7 @@ # extract first number realstart = i pc = s[i] - while i < slen and s[i] != ' ': + while i < slen and s[i] != ' ': if s[i] in ('+','-') and pc not in ('e','E') and i != realstart: break pc = s[i] @@ -136,8 +136,9 @@ except ParseStringError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) else: - #check for overflow - if abs(realval) == OVERFLOWED_FLOAT or abs(imagval) == OVERFLOWED_FLOAT: + # check for overflow + if (abs(realval) == OVERFLOWED_FLOAT or + abs(imagval) == OVERFLOWED_FLOAT): raise OperationError(space.w_ValueError,space.wrap( "complex() literal too large to convert")) @@ -156,8 +157,8 @@ w_real = space.call_function(w_method) # __complex__() could return a string, which space.float() # could accept below... Let's catch this case. - if space.is_true(space.isinstance(w_imag, space.w_str)) or \ - space.is_true(space.isinstance(w_imag, space.w_unicode)): + if (space.is_true(space.isinstance(w_imag, space.w_str)) or + space.is_true(space.isinstance(w_imag, space.w_unicode))): raise OperationError(space.w_TypeError, space.wrap("__complex__() cannot return" " a string")) @@ -205,19 +206,19 @@ space.wrap("descriptor is for 'complex'")) return space.newfloat(getattr(w_obj, name)) return GetSetProperty(fget) - + def descr___getnewargs__(space, w_self): from pypy.objspace.std.complexobject import W_ComplexObject assert isinstance(w_self, W_ComplexObject) - return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) - + return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) + complex_typedef = StdTypeDef("complex", __doc__ = """complex(real[, imag]) -> complex number - + Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""", - __new__ = newmethod(descr__new__), - __getnewargs__ = newmethod(descr___getnewargs__), + __new__ = gateway.interp2app(descr__new__), + __getnewargs__ = gateway.interp2app(descr___getnewargs__), real = complexwprop('realval'), imag = complexwprop('imagval'), ) Modified: pypy/trunk/pypy/objspace/std/default.py ============================================================================== --- pypy/trunk/pypy/objspace/std/default.py (original) +++ pypy/trunk/pypy/objspace/std/default.py Tue Mar 30 00:36:58 2010 @@ -1,6 +1,7 @@ """Default implementation for some operation.""" -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all from pypy.rlib import objectmodel Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Tue Mar 30 00:36:58 2010 @@ -1,6 +1,6 @@ import py, sys -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature Modified: pypy/trunk/pypy/objspace/std/dictproxyobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictproxyobject.py (original) +++ pypy/trunk/pypy/objspace/std/dictproxyobject.py Tue Mar 30 00:36:58 2010 @@ -1,11 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all def descr_get_dictproxy(space, w_obj): return W_DictProxyObject(w_obj.getdict()) class W_DictProxyObject(W_Object): from pypy.objspace.std.dictproxytype import dictproxy_typedef as typedef - + def __init__(w_self, w_dict): w_self.w_dict = w_dict Modified: pypy/trunk/pypy/objspace/std/dictproxytype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dictproxytype.py (original) +++ pypy/trunk/pypy/objspace/std/dictproxytype.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,7 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.interpreter.typedef import GetSetProperty from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/pypy/objspace/std/dicttype.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,8 @@ +from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -124,7 +127,6 @@ def itervalues(d): return iter(dict.values(d)) ''', filename=__file__) -#XXX what about dict.fromkeys()? dict_update__ANY = app.interphook("update") dict_popitem__ANY = app.interphook("popitem") @@ -138,6 +140,24 @@ register_all(vars(), globals()) + at gateway.unwrap_spec(ObjSpace, W_Root, W_Root, W_Root) +def descr_fromkeys(space, w_type, w_keys, w_fill=None): + from pypy.objspace.std.dictmultiobject import W_DictMultiObject + if w_fill is None: + w_fill = space.w_None + w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type) + w_iter = space.iter(w_keys) + while True: + try: + w_key = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + space.setitem(w_dict, w_key, w_fill) + return w_dict + + # ____________________________________________________________ def descr__new__(space, w_dicttype, __args__): @@ -157,9 +177,12 @@ d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)''', - __new__ = newmethod(descr__new__, - unwrap_spec=[gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec= + [gateway.ObjSpace, + gateway.W_Root,gateway.Arguments]), __hash__ = no_hash_descr, + fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True), ) dict_typedef.registermethods(globals()) @@ -180,18 +203,16 @@ XXX to do: remove this __reduce__ method and do a registration with copy_reg, instead. """ - from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('dictiter_surrogate_new') w_typeobj = space.gettypeobject(dictiter_typedef) - - from pypy.interpreter.mixedmodule import MixedModule + raise OperationError( space.w_RuntimeError, space.wrap("cannot pickle dictiters with multidicts")) # XXXXXX get that working again - + # we cannot call __init__ since we don't have the original dict if isinstance(w_self, W_DictIter_Keys): w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj) @@ -217,7 +238,7 @@ w_res ] w_ret = space.newtuple([new_inst, space.newtuple(tup)]) - return w_ret + return w_ret # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/floatobject.py Tue Mar 30 00:36:58 2010 @@ -1,17 +1,22 @@ import operator, new -from pypy.objspace.std.objspace import * from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std import model +from pypy.objspace.std.multimethod import FailedToImplementArgs +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan from pypy.rlib.rarithmetic import formatd, LONG_BIT from pypy.rlib.rbigint import rbigint +from pypy.tool.sourcetools import func_with_new_name import math from pypy.objspace.std.intobject import W_IntObject class W_FloatObject(W_Object): - """This is a reimplementation of the CPython "PyFloatObject" + """This is a reimplementation of the CPython "PyFloatObject" it is assumed that the constructor takes a real Python float as an argument""" from pypy.objspace.std.floattype import float_typedef as typedef @@ -397,11 +402,13 @@ w_float2 = delegate_Long2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, W_NoneObject, order=1) +model.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, + W_NoneObject, order=1) def pow_neg__Int_Int_None(space, w_int1, w_int2, thirdarg): w_float1 = delegate_Int2Float(space, w_int1) w_float2 = delegate_Int2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=2) +model.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=2) Modified: pypy/trunk/pypy/objspace/std/floattype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/floattype.py (original) +++ pypy/trunk/pypy/objspace/std/floattype.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,6 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.strutil import string_to_float, ParseStringError from pypy.objspace.std.strutil import interp_string_to_float @@ -48,5 +49,5 @@ __doc__ = '''float(x) -> floating point number Convert a string or number to a floating point number, if possible.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/trunk/pypy/objspace/std/frozensettype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/frozensettype.py (original) +++ pypy/trunk/pypy/objspace/std/frozensettype.py Tue Mar 30 00:36:58 2010 @@ -1,9 +1,8 @@ -from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM + frozenset_copy = SMM('copy', 1, doc='Return a shallow copy of a set.') @@ -37,7 +36,8 @@ register_all(vars(), globals()) -def descr__frozenset__new__(space, w_frozensettype, w_iterable=NoneNotWrapped): +def descr__frozenset__new__(space, w_frozensettype, + w_iterable=gateway.NoneNotWrapped): from pypy.objspace.std.setobject import W_FrozensetObject from pypy.objspace.std.setobject import _is_frozenset_exact if (space.is_w(w_frozensettype, space.w_frozenset) and @@ -52,7 +52,7 @@ __doc__ = """frozenset(iterable) --> frozenset object Build an immutable unordered collection.""", - __new__ = newmethod(descr__frozenset__new__), + __new__ = gateway.interp2app(descr__frozenset__new__), ) frozenset_typedef.registermethods(globals()) Modified: pypy/trunk/pypy/objspace/std/intobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/intobject.py (original) +++ pypy/trunk/pypy/objspace/std/intobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/trunk/pypy/objspace/std/inttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/inttype.py (original) +++ pypy/trunk/pypy/objspace/std/inttype.py Tue Mar 30 00:36:58 2010 @@ -1,7 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_int, string_to_w_long, ParseStringError, ParseStringOverflowError +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import (string_to_int, string_to_w_long, + ParseStringError, + ParseStringOverflowError) from pypy.rlib.rarithmetic import r_uint from pypy.rlib.objectmodel import instantiate @@ -47,8 +49,8 @@ except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) - -def descr__new__(space, w_inttype, w_x=0, w_base=NoneNotWrapped): + +def descr__new__(space, w_inttype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.intobject import W_IntObject w_longval = None w_value = w_x # 'x' is the keyword argument name in CPython @@ -64,7 +66,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) elif space.is_true(space.isinstance(w_value, space.w_unicode)): if space.config.objspace.std.withropeunicode: from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w @@ -77,7 +79,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) else: # otherwise, use the __int__() method w_obj = space.int(w_value) @@ -116,13 +118,13 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser, base) + w_longval = retry_to_w_long(space, e.parser, base) if w_longval is not None: if not space.is_w(w_inttype, space.w_int): raise OperationError(space.w_OverflowError, space.wrap( - "long int too large to convert to int")) + "long int too large to convert to int")) return w_longval elif space.is_w(w_inttype, space.w_int): # common case @@ -143,5 +145,5 @@ the optional base. It is an error to supply a base when converting a non-string. If the argument is outside the integer range a long object will be returned instead.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/trunk/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/iterobject.py (original) +++ pypy/trunk/pypy/objspace/std/iterobject.py Tue Mar 30 00:36:58 2010 @@ -4,7 +4,9 @@ tested, and complete. The only missing feature is support for function-iteration. """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_AbstractSeqIterObject(W_Object): Modified: pypy/trunk/pypy/objspace/std/itertype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/itertype.py (original) +++ pypy/trunk/pypy/objspace/std/itertype.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/listobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/listobject.py (original) +++ pypy/trunk/pypy/objspace/std/listobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint Modified: pypy/trunk/pypy/objspace/std/listtype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/listtype.py (original) +++ pypy/trunk/pypy/objspace/std/listtype.py Tue Mar 30 00:36:58 2010 @@ -1,6 +1,6 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from sys import maxint @@ -24,7 +24,8 @@ ' occurrences of value') list_reverse = SMM('reverse',1, doc='L.reverse() -- reverse *IN PLACE*') -list_sort = SMM('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse'], +list_sort = SMM('sort', 4, defaults=(None, None, False), + argnames=['cmp', 'key', 'reverse'], doc='L.sort(cmp=None, key=None, reverse=False) -- stable' ' sort *IN PLACE*;\ncmp(x, y) -> -1, 0, 1') list_reversed = SMM('__reversed__', 1, @@ -50,9 +51,9 @@ list_typedef = StdTypeDef("list", __doc__ = '''list() -> new list list(sequence) -> new list initialized from sequence's items''', - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) list_typedef.registermethods(globals()) Modified: pypy/trunk/pypy/objspace/std/longobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/longobject.py (original) +++ pypy/trunk/pypy/objspace/std/longobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,9 @@ import sys -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std import model +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rbigint import rbigint, SHIFT @@ -305,7 +309,8 @@ return %(opname)s__Long_Long(space, w_long1, w_long2) """ % {'opname': opname}, '', 'exec') - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], W_IntObject, W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], + W_IntObject, W_IntObject, order=1) # unary ops for opname in ['neg', 'abs']: @@ -315,7 +320,8 @@ return %(opname)s__Long(space, w_long1) """ % {'opname': opname} - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int' % opname], W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int' % opname], + W_IntObject, order=1) # pow def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3): @@ -328,7 +334,9 @@ w_long2 = delegate_Int2Long(space, w_int2) return pow__Long_Long_Long(space, w_long1, w_long2, w_long3) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=1) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, W_LongObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, + W_LongObject, order=1) Modified: pypy/trunk/pypy/objspace/std/longtype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/longtype.py (original) +++ pypy/trunk/pypy/objspace/std/longtype.py Tue Mar 30 00:36:58 2010 @@ -1,9 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_w_long, ParseStringError from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import string_to_w_long, ParseStringError -def descr__new__(space, w_longtype, w_x=0, w_base=NoneNotWrapped): +def descr__new__(space, w_longtype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.longobject import W_LongObject w_value = w_x # 'x' is the keyword argument name in CPython if w_base is None: @@ -75,5 +75,5 @@ string representation of a floating point number!) When converting a string, use the optional base. It is an error to supply a base when converting a non-string.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/trunk/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/trunk/pypy/objspace/std/marshal_impl.py (original) +++ pypy/trunk/pypy/objspace/std/marshal_impl.py Tue Mar 30 00:36:58 2010 @@ -11,8 +11,8 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all from pypy.rlib.rarithmetic import LONG_BIT +from pypy.objspace.std import longobject, model from pypy.objspace.std.longobject import SHIFT as long_bits -from pypy.objspace.std.objspace import StdObjSpace from pypy.interpreter.special import Ellipsis from pypy.interpreter.pycode import PyCode from pypy.interpreter import gateway, unicodehelper @@ -32,8 +32,6 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.unicodeobject import W_UnicodeObject -import longobject - from pypy.module.marshal.interp_marshal import register TYPE_NULL = '0' @@ -125,7 +123,7 @@ def marshal_w_Ellipsis(space, w_ellipsis, m): m.atom(TYPE_ELLIPSIS) -StdObjSpace.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) +model.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) def unmarshal_Ellipsis(space, u, tc): return space.w_Ellipsis @@ -399,7 +397,7 @@ m.put_int(x.co_firstlineno) m.atom_str(TYPE_STRING, x.co_lnotab) -StdObjSpace.MM.marshal_w.register(marshal_w_pycode, PyCode) +model.MM.marshal_w.register(marshal_w_pycode, PyCode) # helper for unmarshalling string lists of code objects. # unfortunately they now can be interned or referenced, Modified: pypy/trunk/pypy/objspace/std/model.py ============================================================================== --- pypy/trunk/pypy/objspace/std/model.py (original) +++ pypy/trunk/pypy/objspace/std/model.py Tue Mar 30 00:36:58 2010 @@ -8,6 +8,12 @@ import pypy.interpreter.pycode import pypy.interpreter.special +_registered_implementations = set() +def registerimplementation(implcls): + """Hint to objspace.std.model to register the implementation class.""" + assert issubclass(implcls, W_Object) + _registered_implementations.add(implcls) + option_to_typename = { "withsmallint" : ["smallintobject.W_SmallIntObject"], "withstrslice" : ["strsliceobject.W_StringSliceObject"], @@ -132,8 +138,7 @@ if config.objspace.std.withrope: del self.typeorder[stringobject.W_StringObject] - #check if we missed implementations - from pypy.objspace.std.objspace import _registered_implementations + # check if we missed implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or implcls in self.imported_but_not_registered), ( @@ -146,7 +151,7 @@ # register the order in which types are converted into each others # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - + if config.objspace.std.withsmallint: self.typeorder[boolobject.W_BoolObject] += [ (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), @@ -171,11 +176,11 @@ ] self.typeorder[longobject.W_LongObject] += [ (floatobject.W_FloatObject, floatobject.delegate_Long2Float), - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Long2Complex), ] self.typeorder[floatobject.W_FloatObject] += [ - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] self.typeorder[setobject.W_SetObject] += [ @@ -265,6 +270,60 @@ self._typeorder_with_empty_usersubcls = result return self._typeorder_with_empty_usersubcls +def _op_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_1, w_2)) + return op + +def _op_swapped(function): + def op(space, w_1, w_2): + return function(space, w_2, w_1) + return op + +def _op_swapped_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_2, w_1)) + return op + +OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] +OP_CORRESPONDANCES = [ + ('eq', 'ne', _op_negated), + ('lt', 'gt', _op_swapped), + ('le', 'ge', _op_swapped), + ('lt', 'ge', _op_negated), + ('le', 'gt', _op_negated), + ('lt', 'le', _op_swapped_negated), + ('gt', 'ge', _op_swapped_negated), + ] +for op1, op2, value in OP_CORRESPONDANCES[:]: + i = OP_CORRESPONDANCES.index((op1, op2, value)) + OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) + +def add_extra_comparisons(): + """ + Add the missing comparison operators if they were not explicitly + defined: eq <-> ne and lt <-> le <-> gt <-> ge. + We try to add them in the order defined by the OP_CORRESPONDANCES + table, thus favouring swapping the arguments over negating the result. + """ + originalentries = {} + for op in OPERATORS: + originalentries[op] = getattr(MM, op).signatures() + + for op1, op2, correspondance in OP_CORRESPONDANCES: + mirrorfunc = getattr(MM, op2) + for types in originalentries[op1]: + t1, t2 = types + if t1 is t2: + if not mirrorfunc.has_signature(types): + functions = getattr(MM, op1).getfunctions(types) + assert len(functions) == 1, ('Automatic' + ' registration of comparison functions' + ' only work when there is a single method for' + ' the operation.') + mirrorfunc.register(correspondance(functions[0]), *types) + + # ____________________________________________________________ W_ANY = W_Root @@ -313,13 +372,13 @@ break else: self.name = operatorsymbol - + if extras.get('general__args__', False): self.argnames_after = ['__args__'] if extras.get('w_varargs', False): self.argnames_after = ['w_args'] if extras.get('varargs_w', False): - self.argnames_after = ['args_w'] + self.argnames_after = ['args_w'] self.argnames_after += extras.get('extra_args', []) def install_not_sliced(self, typeorder, baked_perform_call=True): @@ -352,3 +411,32 @@ # mm.dispatch_tree = merge(self.dispatch_tree, other.dispatch_tree) return mm + + +class MM: + """StdObjSpace multimethods""" + + call = StdObjSpaceMultiMethod('call', 1, ['__call__'], + general__args__=True) + init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) + getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) + # special visible multimethods + int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int + str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string + float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float + uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) + unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters + bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint + # NOTE: when adding more sometype_w() methods, you need to write a + # stub in default.py to raise a space.w_TypeError + marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) + + # add all regular multimethods here + for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: + if _name not in locals(): + mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) + locals()[_name] = mm + del mm + + pow.extras['defaults'] = (None,) Modified: pypy/trunk/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/noneobject.py (original) +++ pypy/trunk/pypy/objspace/std/noneobject.py Tue Mar 30 00:36:58 2010 @@ -2,9 +2,10 @@ None Object implementation ok and tested -""" +""" -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_NoneObject(W_Object): from pypy.objspace.std.nonetype import none_typedef as typedef Modified: pypy/trunk/pypy/objspace/std/nonetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/nonetype.py (original) +++ pypy/trunk/pypy/objspace/std/nonetype.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,4 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/trunk/pypy/objspace/std/objectobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objectobject.py (original) +++ pypy/trunk/pypy/objspace/std/objectobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import W_Object, register_all +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all class W_ObjectObject(W_Object): Modified: pypy/trunk/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objecttype.py (original) +++ pypy/trunk/pypy/objspace/std/objecttype.py Tue Mar 30 00:36:58 2010 @@ -1,10 +1,9 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.objspace.descroperation import Object +from pypy.interpreter.typedef import GetSetProperty, default_identity_hash from pypy.interpreter import gateway -from pypy.interpreter.typedef import default_identity_hash -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.descroperation import Object +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.objspace import StdObjSpace def descr__repr__(space, w_obj): @@ -171,8 +170,8 @@ __repr__ = gateway.interp2app(descr__repr__), __class__ = GetSetProperty(descr__class__, descr_set___class__), __doc__ = '''The most base type''', - __new__ = newmethod(descr__new__, - unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), __hash__ = gateway.interp2app(default_identity_hash), __reduce_ex__ = gateway.interp2app(descr__reduce_ex__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,int]), Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Mar 30 00:36:58 2010 @@ -1,33 +1,42 @@ -from pypy.objspace.std.register_all import register_all +import __builtin__ +import types +from pypy.interpreter import pyframe, function, special from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, operationerrfmt, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter import pyframe, function +from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, + transparent, callmethod) +from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized -from pypy.interpreter.gateway import PyPyCacheDir -from pypy.tool.cache import Cache -from pypy.tool.sourcetools import func_with_new_name -from pypy.objspace.std.model import W_Object, UnwrapError -from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel -from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs -from pypy.objspace.descroperation import DescrOperation, raiseattrerror -from pypy.objspace.std import stdtypedef, frame from pypy.rlib.rarithmetic import base_int from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.jit import hint -import sys -import os -import __builtin__ - -_registered_implementations = {} -def registerimplementation(implcls): - # hint to objspace.std.model to register the implementation class - assert issubclass(implcls, W_Object) - _registered_implementations[implcls] = True +from pypy.tool.sourcetools import func_with_new_name +# Object imports +from pypy.objspace.std.boolobject import W_BoolObject +from pypy.objspace.std.complexobject import W_ComplexObject +from pypy.objspace.std.dictmultiobject import W_DictMultiObject +from pypy.objspace.std.floatobject import W_FloatObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.longobject import W_LongObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.ropeobject import W_RopeObject +from pypy.objspace.std.iterobject import W_SeqIterObject +from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.smallintobject import W_SmallIntObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.typeobject import W_TypeObject + +# types +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.stringtype import wrapstr +from pypy.objspace.std.unicodetype import wrapunicode -################################################################## class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object @@ -35,91 +44,36 @@ def initialize(self): "NOT_RPYTHON: only for initializing the space." - # Import all the object types and implementations - self.model = StdTypeModel(self.config) + # setup all the object types and implementations + self.model = model.StdTypeModel(self.config) self.FrameClass = frame.build_frame(self) - # store the dict class on the space to access it in various places - from pypy.objspace.std import dictmultiobject - self.DictObjectCls = dictmultiobject.W_DictMultiObject - - from pypy.objspace.std import tupleobject - self.TupleObjectCls = tupleobject.W_TupleObject - - if not self.config.objspace.std.withrope: - from pypy.objspace.std import stringobject - self.StringObjectCls = stringobject.W_StringObject - else: - from pypy.objspace.std import ropeobject - self.StringObjectCls = ropeobject.W_RopeObject - assert self.StringObjectCls in self.model.typeorder - - # install all the MultiMethods into the space instance - for name, mm in self.MM.__dict__.items(): - if not isinstance(mm, StdObjSpaceMultiMethod): - continue - if not hasattr(self, name): - if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object - func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) - else: - exprargs, expr, miniglobals, fallback = ( - mm.install_not_sliced(self.model.typeorder, baked_perform_call=False)) - - func = stdtypedef.make_perform_trampoline('__mm_'+name, - exprargs, expr, miniglobals, - mm) - - # e.g. add(space, w_x, w_y) - def make_boundmethod(func=func): - def boundmethod(*args): - return func(self, *args) - return func_with_new_name(boundmethod, 'boundmethod_'+name) - boundmethod = make_boundmethod() - setattr(self, name, boundmethod) # store into 'space' instance - elif self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut - if name.startswith('inplace_'): - fallback_name = name[len('inplace_'):] - if fallback_name in ('or', 'and'): - fallback_name += '_' - fallback_mm = self.MM.__dict__[fallback_name] - else: - fallback_mm = None - builtinshortcut.install(self, mm, fallback_mm) + if self.config.objspace.std.withrope: + self.StringObjectCls = W_RopeObject + else: + self.StringObjectCls = W_StringObject - if self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut - builtinshortcut.install_is_true(self, self.MM.nonzero, self.MM.len) + self._install_multimethods() - # set up the method cache if self.config.objspace.std.withmethodcache: - SIZE = 1 << self.config.objspace.std.methodcachesizeexp - self.method_cache_versions = [None] * SIZE - self.method_cache_names = [None] * SIZE - self.method_cache_lookup_where = [(None, None)] * SIZE - if self.config.objspace.std.withmethodcachecounter: - self.method_cache_hits = {} - self.method_cache_misses = {} - - # hack to avoid imports in the time-critical functions below - for cls in self.model.typeorder: - globals()[cls.__name__] = cls - for cls in self.model.imported_but_not_registered: - globals()[cls.__name__] = cls + self._setup_method_cache() # singletons - self.w_None = W_NoneObject.w_None + self.w_None = W_NoneObject.w_None self.w_False = W_BoolObject.w_False - self.w_True = W_BoolObject.w_True - from pypy.interpreter.special import NotImplemented, Ellipsis - self.w_NotImplemented = self.wrap(NotImplemented(self)) - self.w_Ellipsis = self.wrap(Ellipsis(self)) + self.w_True = W_BoolObject.w_True + self.w_NotImplemented = self.wrap(special.NotImplemented(self)) + self.w_Ellipsis = self.wrap(special.Ellipsis(self)) # types + self.builtin_types = {} for typedef in self.model.pythontypes: w_type = self.gettypeobject(typedef) + self.builtin_types[typedef.name] = w_type setattr(self, 'w_' + typedef.name, w_type) + self.builtin_types["NotImplemented"] = self.w_NotImplemented + self.builtin_types["Ellipsis"] = self.w_Ellipsis # exceptions & builtins self.make_builtins() @@ -127,34 +81,57 @@ # the type of old-style classes self.w_classobj = self.builtin.get('__metaclass__') - # fix up a problem where multimethods apparently don't - # like to define this at interp-level - # HACK HACK HACK - from pypy.objspace.std.typeobject import _HEAPTYPE - old_flags = self.w_dict.__flags__ - self.w_dict.__flags__ |= _HEAPTYPE - self.appexec([self.w_dict], """ - (dict): - def fromkeys(cls, seq, value=None): - r = cls() - for s in seq: - r[s] = value - return r - dict.fromkeys = classmethod(fromkeys) - """) - self.w_dict.__flags__ = old_flags - # final setup self.setup_builtin_modules() # Adding transparent proxy call if self.config.objspace.std.withtproxy: - w___pypy__ = self.getbuiltinmodule("__pypy__") - from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - - self.setattr(w___pypy__, self.wrap('tproxy'), - self.wrap(app_proxy)) - self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), - self.wrap(app_proxy_controller)) + transparent.setup(self) + + def get_builtin_types(self): + return self.builtin_types + + def _setup_method_cache(self): + SIZE = 1 << self.config.objspace.std.methodcachesizeexp + self.method_cache_versions = [None] * SIZE + self.method_cache_names = [None] * SIZE + self.method_cache_lookup_where = [(None, None)] * SIZE + if self.config.objspace.std.withmethodcachecounter: + self.method_cache_hits = {} + self.method_cache_misses = {} + + def _install_multimethods(self): + """Install all the MultiMethods into the space instance.""" + model.add_extra_comparisons() + for name, mm in model.MM.__dict__.items(): + if not isinstance(mm, model.StdObjSpaceMultiMethod): + continue + if not hasattr(self, name): + # int_w, str_w...: these do not return a wrapped object + if name.endswith('_w'): + func = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=True) + else: + unsliced = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=False) + exprargs, expr, miniglobals, fallback = unsliced + func = stdtypedef.make_perform_trampoline('__mm_'+name, + exprargs, expr, + miniglobals, mm) + + boundmethod = types.MethodType(func, self, self.__class__) + setattr(self, name, boundmethod) # store into 'space' instance + elif self.config.objspace.std.builtinshortcut: + if name.startswith('inplace_'): + fallback_name = name[len('inplace_'):] + if fallback_name in ('or', 'and'): + fallback_name += '_' + fallback_mm = model.MM.__dict__[fallback_name] + else: + fallback_mm = None + builtinshortcut.install(self, mm, fallback_mm) + if self.config.objspace.std.builtinshortcut: + builtinshortcut.install_is_true(self, model.MM.nonzero, + model.MM.len) def createexecutioncontext(self): # add space specific fields to execution context @@ -190,7 +167,7 @@ # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None - if isinstance(x, W_Object): + if isinstance(x, model.W_Object): raise TypeError, "attempt to wrap already wrapped object: %s"%(x,) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% @@ -201,10 +178,8 @@ else: return self.newint(x) if isinstance(x, str): - from pypy.objspace.std.stringtype import wrapstr return wrapstr(self, x) if isinstance(x, unicode): - from pypy.objspace.std.unicodetype import wrapunicode return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) @@ -266,7 +241,6 @@ w_result = self.wrap_exception_cls(x) if w_result is not None: return w_result - #print "fake-wrapping", x from fake import fake_object return fake_object(self, x) @@ -275,23 +249,22 @@ def wrap_exception_cls(self, x): """NOT_RPYTHON""" if hasattr(self, 'w_' + x.__name__): - w_result = getattr(self, 'w_' + x.__name__) + w_result = getattr(self, 'w_' + x.__name__) return w_result return None wrap_exception_cls._annspecialcase_ = "override:wrap_exception_cls" - + def unwrap(self, w_obj): if isinstance(w_obj, Wrappable): return w_obj - if isinstance(w_obj, W_Object): + if isinstance(w_obj, model.W_Object): return w_obj.unwrap(self) - raise UnwrapError, "cannot unwrap: %r" % w_obj + raise model.UnwrapError, "cannot unwrap: %r" % w_obj def newint(self, intval): # this time-critical and circular-imports-funny method was stored # on 'self' by initialize() # not sure how bad this is: - from pypy.objspace.std.inttype import wrapint return wrapint(self, intval) def newfloat(self, floatval): @@ -304,18 +277,15 @@ return W_LongObject.fromint(self, val) def newtuple(self, list_w): - from pypy.objspace.std.tupletype import wraptuple assert isinstance(list_w, list) make_sure_not_resized(list_w) - return wraptuple(self, list_w) + return W_TupleObject(list_w) def newlist(self, list_w): - from pypy.objspace.std.listobject import W_ListObject return W_ListObject(list_w) def newdict(self, module=False, instance=False, classofinstance=None, from_strdict_shared=None, strdict=False): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject return W_DictMultiObject.allocate_and_init_instance( self, module=module, instance=instance, classofinstance=classofinstance, @@ -493,21 +463,21 @@ def finditem_str(self, w_obj, key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem_str(key) return ObjSpace.finditem_str(self, w_obj, key) def finditem(self, w_obj, w_key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem(w_key) return ObjSpace.finditem(self, w_obj, w_key) def set_str_keyed_item(self, w_obj, key, w_value, shadows_type=True): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): w_obj.set_str_keyed_item(key, w_value, shadows_type) else: @@ -528,37 +498,10 @@ def call_method(self, w_obj, methname, *arg_w): if self.config.objspace.opcodes.CALL_METHOD: - from pypy.objspace.std.callmethod import call_method_opt - return call_method_opt(self, w_obj, methname, *arg_w) + return callmethod.call_method_opt(self, w_obj, methname, *arg_w) else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) 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) - init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) - getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) - # special visible multimethods - int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int - str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string - float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float - uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) - unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters - bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint - # NOTE: when adding more sometype_w() methods, you need to write a - # stub in default.py to raise a space.w_TypeError - marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) - log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) - - # add all regular multimethods here - for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if _name not in locals(): - mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) - locals()[_name] = mm - del mm - - pow.extras['defaults'] = (None,) Modified: pypy/trunk/pypy/objspace/std/proxyobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/proxyobject.py (original) +++ pypy/trunk/pypy/objspace/std/proxyobject.py Tue Mar 30 00:36:58 2010 @@ -2,7 +2,7 @@ """ transparent list implementation """ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.proxy_helpers import register_type from pypy.interpreter.error import OperationError from pypy.interpreter import baseobjspace, argument @@ -73,7 +73,7 @@ W_Transparent.__name__ = name return W_Transparent -W_Transparent = transparent_class('W_Transparent', Wrappable) +W_Transparent = transparent_class('W_Transparent', baseobjspace.Wrappable) W_TransparentObject = transparent_class('W_TransparentObject', W_Object) from pypy.objspace.std.objecttype import object_typedef Modified: pypy/trunk/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/rangeobject.py (original) +++ pypy/trunk/pypy/objspace/std/rangeobject.py Tue Mar 30 00:36:58 2010 @@ -1,12 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.inttype import wrapint 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 - -from pypy.objspace.std import slicetype +from pypy.objspace.std import listtype, iterobject, slicetype from pypy.interpreter import gateway, baseobjspace def length(start, stop, step): Modified: pypy/trunk/pypy/objspace/std/register_all.py ============================================================================== --- pypy/trunk/pypy/objspace/std/register_all.py (original) +++ pypy/trunk/pypy/objspace/std/register_all.py Tue Mar 30 00:36:58 2010 @@ -1,60 +1,49 @@ +from pypy.objspace.std import model, stdtypedef _name_mappings = { 'and': 'and_', 'or': 'or_', } - + def register_all(module_dict, *alt_ns): - """register implementations for multimethods. + """register implementations for multimethods. By default a (name, object) pair of the given module dictionary is registered on the multimethod 'name' of StdObjSpace. If the name doesn't exist then the alternative namespace is tried - for registration. + for registration. """ - from pypy.objspace.std.objspace import StdObjSpace - from pypy.objspace.std.model import W_ANY, W_Object - from pypy.objspace.std.stdtypedef import StdTypeDef - namespaces = list(alt_ns) + [StdObjSpace.MM, StdObjSpace] + namespaces = list(alt_ns) + [model.MM] for name, obj in module_dict.items(): - if name.startswith('app_'): - print "%s: direct app definitions deprecated" % name + if name.startswith('app_'): + print "%s: direct app definitions deprecated" % name if name.find('__')<1 or name.startswith('app_'): continue funcname, sig = name.split('__') l=[] for i in sig.split('_'): if i == 'ANY': # just in case W_ANY is not in module_dict - icls = W_ANY + icls = model.W_ANY elif i == 'Object': # just in case W_Object is not in module_dict - icls = W_Object + icls = model.W_Object else: icls = (module_dict.get('W_%s' % i) or module_dict.get('W_%sObject' % i)) if icls is None: x = module_dict.get(i) - if isinstance(x, StdTypeDef): + if isinstance(x, stdtypedef.StdTypeDef): icls = x.any if icls is None: raise ValueError, \ "no W_%s or W_%sObject for the definition of %s" % ( i, i, name) l.append(icls) - - #XXX trying to be too clever at the moment for userobject.SpecialMethod - #if len(l) != obj.func_code.co_argcount-1: - # raise ValueError, \ - # "function name %s doesn't specify exactly %d arguments" % ( - # repr(name), obj.func_code.co_argcount-1) - funcname = _name_mappings.get(funcname, funcname) func = hack_func_by_name(funcname, namespaces) func.register(obj, *l) - add_extra_comparisons() - def hack_func_by_name(funcname, namespaces): for ns in namespaces: @@ -64,76 +53,5 @@ else: if hasattr(ns, funcname): return getattr(ns, funcname) - #import typetype - #try: - # return getattr(typetype.W_TypeType, funcname) - #except AttributeError: - # pass # catches not only the getattr() but the typetype.W_TypeType - # # in case it is not fully imported yet :-(((( - from pypy.objspace.std import objecttype - try: - return getattr(objecttype, funcname) - except AttributeError: - pass raise NameError, ("trying hard but not finding a multimethod named %s" % funcname) - - -def op_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_1, w_2)) - return op - -def op_swapped(function): - def op(space, w_1, w_2): - return function(space, w_2, w_1) - return op - -def op_swapped_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_2, w_1)) - return op - -OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] -OP_CORRESPONDANCES = [ - ('eq', 'ne', op_negated), - ('lt', 'gt', op_swapped), - ('le', 'ge', op_swapped), - ('lt', 'ge', op_negated), - ('le', 'gt', op_negated), - ('lt', 'le', op_swapped_negated), - ('gt', 'ge', op_swapped_negated), - ] -for op1, op2, value in OP_CORRESPONDANCES[:]: - i = OP_CORRESPONDANCES.index((op1, op2, value)) - OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) - -def add_extra_comparisons(): - """ - Add the missing comparison operators if they were not explicitly - defined: eq <-> ne and lt <-> le <-> gt <-> ge. - We try to add them in the order defined by the OP_CORRESPONDANCES - table, thus favouring swapping the arguments over negating the result. - """ - from pypy.objspace.std.objspace import StdObjSpace - originalentries = {} - for op in OPERATORS: - originalentries[op] = getattr(StdObjSpace.MM, op).signatures() - - for op1, op2, correspondance in OP_CORRESPONDANCES: - mirrorfunc = getattr(StdObjSpace.MM, op2) - for types in originalentries[op1]: - t1, t2 = types - if t1 is t2: - if not mirrorfunc.has_signature(types): - functions = getattr(StdObjSpace.MM, op1).getfunctions(types) - assert len(functions) == 1, ('Automatic' - ' registration of comparison functions' - ' only work when there is a single method for' - ' the operation.') - #print 'adding %s <<<%s>>> %s as %s(%s)' % ( - # t1, op2, t2, - # correspondance.func_name, functions[0].func_name) - mirrorfunc.register( - correspondance(functions[0]), - *types) Modified: pypy/trunk/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/trunk/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/ropeunicodeobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/trunk/pypy/objspace/std/setobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/setobject.py (original) +++ pypy/trunk/pypy/objspace/std/setobject.py Tue Mar 30 00:36:58 2010 @@ -1,7 +1,8 @@ -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.rlib.objectmodel import r_dict from pypy.rlib.rarithmetic import intmask, r_uint +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway from pypy.interpreter.argument import Signature from pypy.objspace.std.settype import set_typedef as settypedef Modified: pypy/trunk/pypy/objspace/std/settype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/settype.py (original) +++ pypy/trunk/pypy/objspace/std/settype.py Tue Mar 30 00:36:58 2010 @@ -1,8 +1,7 @@ from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod, no_hash_descr -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr, SMM from pypy.interpreter import gateway set_add = SMM('add', 2, @@ -77,9 +76,9 @@ __doc__ = """set(iterable) --> set object Build an unordered collection.""", - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) Modified: pypy/trunk/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/sliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/sliceobject.py Tue Mar 30 00:36:58 2010 @@ -5,8 +5,10 @@ indices method tested, OK """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.slicetype import _Eval_SliceIndex Modified: pypy/trunk/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/slicetype.py (original) +++ pypy/trunk/pypy/objspace/std/slicetype.py Tue Mar 30 00:36:58 2010 @@ -1,6 +1,6 @@ -import sys -from pypy.interpreter import baseobjspace -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import baseobjspace, gateway +from pypy.interpreter.typedef import GetSetProperty +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -88,7 +88,7 @@ __doc__ = '''slice([start,] stop[, step]) Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __hash__ = no_hash_descr, start = slicewprop('w_start'), stop = slicewprop('w_stop'), Modified: pypy/trunk/pypy/objspace/std/smallintobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/smallintobject.py (original) +++ pypy/trunk/pypy/objspace/std/smallintobject.py Tue Mar 30 00:36:58 2010 @@ -2,7 +2,10 @@ Implementation of small ints, stored as odd-valued pointers in the translated PyPy. To enable them, see inttype.py. """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.objspace.std.inttype import wrapint Modified: pypy/trunk/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stdtypedef.py (original) +++ pypy/trunk/pypy/objspace/std/stdtypedef.py Tue Mar 30 00:36:58 2010 @@ -4,14 +4,13 @@ from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict from pypy.interpreter.baseobjspace import SpaceCache +from pypy.objspace.std import model from pypy.objspace.std.model import StdObjSpaceMultiMethod from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib import jit from pypy.tool.sourcetools import compile2 -__all__ = ['StdTypeDef', 'newmethod', 'gateway', - 'GetSetProperty', 'Member', - 'SMM', 'descr_get_dict', 'no_hash_descr'] +__all__ = ['StdTypeDef', 'SMM', 'no_hash_descr'] SMM = StdObjSpaceMultiMethod @@ -42,11 +41,6 @@ std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict) std_dict_descr.name = '__dict__' -def newmethod(descr_new, unwrap_spec=None): - "NOT_RPYTHON: initialization-time only." - # this is turned into a static method by the constructor of W_TypeObject. - return gateway.interp2app(descr_new, unwrap_spec=unwrap_spec) - # ____________________________________________________________ # # All the code below fishes from the multimethod registration tables @@ -288,8 +282,8 @@ def slicemultimethods(space, typedef): """NOT_RPYTHON""" result = {} - # import and slice all multimethods of the space.MM container - for multimethod in hack_out_multimethods(space.MM.__dict__): + # import and slice all multimethods of the MM container + for multimethod in hack_out_multimethods(model.MM.__dict__): slicemultimethod(space, multimethod, typedef, result) # import all multimethods defined directly on the type without slicing for multimethod in typedef.local_multimethods: @@ -301,9 +295,8 @@ multimethods that have an implementation whose first typed argument is 'cls'. """ - from pypy.objspace.std.objspace import StdObjSpace # XXX for now typedef = cls.typedef - for multimethod in hack_out_multimethods(StdObjSpace.MM.__dict__): + for multimethod in hack_out_multimethods(model.MM.__dict__): if cls in multimethod.dispatch_tree: yield multimethod, False for multimethod in typedef.local_multimethods: Modified: pypy/trunk/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringobject.py (original) +++ pypy/trunk/pypy/objspace/std/stringobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/trunk/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/stringtype.py (original) +++ pypy/trunk/pypy/objspace/std/stringtype.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.basestringtype import basestring_typedef from sys import maxint @@ -42,7 +43,7 @@ def sliced(space, s, start, stop, orig_obj): assert start >= 0 - assert stop >= 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 @@ -294,7 +295,7 @@ # ____________________________________________________________ str_typedef = StdTypeDef("str", basestring_typedef, - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __doc__ = '''str(object) -> string Return a nice string representation of the object. @@ -326,4 +327,3 @@ if u_self[start+i] != prefix[i]: return False return True - Modified: pypy/trunk/pypy/objspace/std/strjoinobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/strjoinobject.py (original) +++ pypy/trunk/pypy/objspace/std/strjoinobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode Modified: pypy/trunk/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/strsliceobject.py (original) +++ pypy/trunk/pypy/objspace/std/strsliceobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice 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 Tue Mar 30 00:36:58 2010 @@ -1,7 +1,7 @@ import py from pypy.objspace.std import complexobject as cobj from pypy.objspace.std import complextype as cobjtype -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std import StdObjSpace Modified: pypy/trunk/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_floatobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ from pypy.objspace.std import floatobject as fobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement import py class TestW_FloatObject: Modified: pypy/trunk/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_intobject.py Tue Mar 30 00:36:58 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import intobject as iobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/trunk/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_longobject.py Tue Mar 30 00:36:58 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import longobject as lobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/trunk/pypy/objspace/std/test/test_smallintobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/test/test_smallintobject.py (original) +++ pypy/trunk/pypy/objspace/std/test/test_smallintobject.py Tue Mar 30 00:36:58 2010 @@ -5,7 +5,7 @@ # py.test.skip("WITHSMALLINT is not enabled") from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint from pypy.objspace.std.test.test_intobject import AppTestInt 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 Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import * -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.conftest import gettestobjspace from pypy.objspace.std.typeobject import W_TypeObject @@ -15,7 +15,7 @@ def descr__new__(space, w_subtype): return space.allocate_instance(W_Stuff, w_subtype) W_Stuff.typedef = StdTypeDef("stuff", - __new__ = newmethod(descr__new__)) + __new__ = interp2app(descr__new__)) W_Stuff.typedef.acceptable_as_base_class = False w_stufftype = space.gettypeobject(W_Stuff.typedef) space.appexec([w_stufftype], """(stufftype): Modified: pypy/trunk/pypy/objspace/std/transparent.py ============================================================================== --- pypy/trunk/pypy/objspace/std/transparent.py (original) +++ pypy/trunk/pypy/objspace/std/transparent.py Tue Mar 30 00:36:58 2010 @@ -20,6 +20,16 @@ type_cache = TypeCache() + +def setup(space): + """Add proxy functions to the __pypy__ module.""" + w___pypy__ = space.getbuiltinmodule("__pypy__") + space.setattr(w___pypy__, space.wrap('tproxy'), space.wrap(app_proxy)) + space.setattr(w___pypy__, space.wrap('get_tproxy_controller'), + space.wrap(app_proxy_controller)) + + + def proxy(space, w_type, w_controller): """tproxy(typ, controller) -> obj Return something that looks like it is of type typ. Its behaviour is Modified: pypy/trunk/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/tupleobject.py (original) +++ pypy/trunk/pypy/objspace/std/tupleobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,8 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import intmask from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway @@ -8,7 +11,7 @@ class W_TupleObject(W_Object): from pypy.objspace.std.tupletype import tuple_typedef as typedef _immutable_ = True - + def __init__(w_self, wrappeditems): make_sure_not_resized(wrappeditems) w_self.wrappeditems = wrappeditems # a list of wrapped values Modified: pypy/trunk/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/tupletype.py (original) +++ pypy/trunk/pypy/objspace/std/tupletype.py Tue Mar 30 00:36:58 2010 @@ -1,11 +1,7 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef -def wraptuple(space, list_w): - from pypy.objspace.std.tupleobject import W_TupleObject - return W_TupleObject(list_w) - -def descr__new__(space, w_tupletype, w_sequence=NoneNotWrapped): +def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped): from pypy.objspace.std.tupleobject import W_TupleObject if w_sequence is None: tuple_w = [] @@ -14,8 +10,8 @@ return w_sequence else: tuple_w = space.fixedview(w_sequence) - w_obj = space.allocate_instance(space.TupleObjectCls, w_tupletype) - space.TupleObjectCls.__init__(w_obj, tuple_w) + w_obj = space.allocate_instance(W_TupleObject, w_tupletype) + W_TupleObject.__init__(w_obj, tuple_w) return w_obj # ____________________________________________________________ @@ -25,5 +21,5 @@ tuple(sequence) -> tuple initialized from sequence's items If the argument is a tuple, the return value is the same object.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Tue Mar 30 00:36:58 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt Modified: pypy/trunk/pypy/objspace/std/typetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typetype.py (original) +++ pypy/trunk/pypy/objspace/std/typetype.py Tue Mar 30 00:36:58 2010 @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments -from pypy.interpreter.typedef import weakref_descr -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, + weakref_descr) +from pypy.objspace.std.stdtypedef import StdTypeDef def descr__new__(space, w_typetype, w_name, w_bases, w_dict): "This is used to create user-defined classes only." @@ -10,7 +11,7 @@ # XXX check types w_typetype = _precheck_for_new(space, w_typetype) - + bases_w = space.fixedview(w_bases) w_winner = w_typetype @@ -34,7 +35,7 @@ if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))): return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict) w_typetype = w_winner - + name = space.str_w(w_name) assert isinstance(name, str) dict_w = {} @@ -187,7 +188,7 @@ return space.get(w_result, space.w_None, w_type) def descr__flags(space, w_type): - w_type = _check(space, w_type) + w_type = _check(space, w_type) return space.wrap(w_type.__flags__) def descr_get__module(space, w_type): @@ -195,9 +196,9 @@ return w_type.get_module() def descr_set__module(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__module__", w_type.name) w_type.mutated() @@ -211,7 +212,7 @@ # ____________________________________________________________ type_typedef = StdTypeDef("type", - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __name__ = GetSetProperty(descr_get__name__, descr_set__name__), __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__), __base__ = GetSetProperty(descr__base), Modified: pypy/trunk/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodeobject.py (original) +++ pypy/trunk/pypy/objspace/std/unicodeobject.py Tue Mar 30 00:36:58 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt Modified: pypy/trunk/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/unicodetype.py (original) +++ pypy/trunk/pypy/objspace/std/unicodetype.py Tue Mar 30 00:36:58 2010 @@ -1,8 +1,8 @@ +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -286,7 +286,7 @@ # ____________________________________________________________ unicode_typedef = StdTypeDef("unicode", basestring_typedef, - __new__ = newmethod(descr_new_), + __new__ = gateway.interp2app(descr_new_), __doc__ = '''unicode(string [, encoding[, errors]]) -> object Create a new Unicode object from the given encoded string. From benjamin at codespeak.net Tue Mar 30 00:39:15 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:39:15 +0200 (CEST) Subject: [pypy-svn] r73148 - pypy/trunk/pypy/objspace/std Message-ID: <20100329223915.DB40B282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:39:14 2010 New Revision: 73148 Removed: pypy/trunk/pypy/objspace/std/mro.py Log: this reference isn't really needed From benjamin at codespeak.net Tue Mar 30 00:39:46 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:39:46 +0200 (CEST) Subject: [pypy-svn] r73149 - pypy/branch/cleanup-objspace-init Message-ID: <20100329223946.11ED7282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:39:44 2010 New Revision: 73149 Removed: pypy/branch/cleanup-objspace-init/ Log: remove merged branch From benjamin at codespeak.net Tue Mar 30 00:49:35 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:49:35 +0200 (CEST) Subject: [pypy-svn] r73150 - pypy/trunk/pypy/objspace/std Message-ID: <20100329224935.26650282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:49:33 2010 New Revision: 73150 Modified: pypy/trunk/pypy/objspace/std/model.py Log: rewrap Modified: pypy/trunk/pypy/objspace/std/model.py ============================================================================== --- pypy/trunk/pypy/objspace/std/model.py (original) +++ pypy/trunk/pypy/objspace/std/model.py Tue Mar 30 00:49:33 2010 @@ -335,11 +335,7 @@ __slots__ = () def __repr__(self): - s = '%s(%s)' % ( - self.__class__.__name__, - #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) - getattr(self, 'name', '') - ) + s = '%s(%s)' % (self.__class__.__name__, getattr(self, 'name', ''))) w_cls = getattr(self, 'w__class__', None) if w_cls is not None and w_cls is not self: s += ' instance of %s' % self.w__class__ From benjamin at codespeak.net Tue Mar 30 00:51:41 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:51:41 +0200 (CEST) Subject: [pypy-svn] r73151 - pypy/trunk/pypy/objspace/std Message-ID: <20100329225141.B1233282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:51:40 2010 New Revision: 73151 Modified: pypy/trunk/pypy/objspace/std/model.py Log: kill paren Modified: pypy/trunk/pypy/objspace/std/model.py ============================================================================== --- pypy/trunk/pypy/objspace/std/model.py (original) +++ pypy/trunk/pypy/objspace/std/model.py Tue Mar 30 00:51:40 2010 @@ -335,7 +335,7 @@ __slots__ = () def __repr__(self): - s = '%s(%s)' % (self.__class__.__name__, getattr(self, 'name', ''))) + s = '%s(%s)' % (self.__class__.__name__, getattr(self, 'name', '')) w_cls = getattr(self, 'w__class__', None) if w_cls is not None and w_cls is not self: s += ' instance of %s' % self.w__class__ From benjamin at codespeak.net Tue Mar 30 00:58:00 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 00:58:00 +0200 (CEST) Subject: [pypy-svn] r73152 - pypy/trunk/pypy/objspace/std Message-ID: <20100329225800.24263282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 00:57:58 2010 New Revision: 73152 Modified: pypy/trunk/pypy/objspace/std/iterobject.py pypy/trunk/pypy/objspace/std/sliceobject.py Log: remove old review comments Modified: pypy/trunk/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/iterobject.py (original) +++ pypy/trunk/pypy/objspace/std/iterobject.py Tue Mar 30 00:57:58 2010 @@ -1,9 +1,4 @@ -""" -Reviewed 03-06-22 -Sequence-iteration is correctly implemented, thoroughly -tested, and complete. The only missing feature is support -for function-iteration. -""" +"""Generic iterator implementations""" from pypy.interpreter.error import OperationError from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.register_all import register_all @@ -11,7 +6,7 @@ class W_AbstractSeqIterObject(W_Object): from pypy.objspace.std.itertype import iter_typedef as typedef - + def __init__(w_self, w_seq, index=0): if index < 0: index = 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 Mar 30 00:57:58 2010 @@ -1,9 +1,4 @@ -""" -Reviewed 03-06-21 - -slice object construction tested, OK -indices method tested, OK -""" +"""Slice object""" from pypy.interpreter.error import OperationError from pypy.interpreter import gateway From xoraxax at codespeak.net Tue Mar 30 01:50:03 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 01:50:03 +0200 (CEST) Subject: [pypy-svn] r73153 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100329235003.E3E46282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 01:50:01 2010 New Revision: 73153 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Log: RPythonication and correctness fixes. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Tue Mar 30 01:50:01 2010 @@ -36,10 +36,10 @@ self.w_objclass = from_ref(space, pyo) def __repr__(self): - return "" % (self.name, self.w_objclass.getname(self.space, '?')) + self.space.unwrap(self.descr_method_repr()) def descr_method_repr(self): - return self.space.wrap(self.__repr__()) + return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space, '?'))) class W_PyCWrapperObject(Wrappable): @@ -66,7 +66,7 @@ return self.wrapper_func(space, w_self, w_args, self.func) def descr_method_repr(self): - return self.space.wrap("" % (self.method_name, + return self.space.wrap("" % (self.method_name, self.w_objclass.getname(self.space, '?'))) @unwrap_spec(ObjSpace, W_Root, Arguments) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Tue Mar 30 01:50:01 2010 @@ -51,7 +51,7 @@ methodname = rffi.charp2str(method.c_ml_name) flags = rffi.cast(lltype.Signed, method.c_ml_flags) - if pto is None: + if not pto: if flags & METH_CLASS or flags & METH_STATIC: raise OperationError(space.w_ValueError, space.wrap("module functions cannot set METH_CLASS or METH_STATIC")) From xoraxax at codespeak.net Tue Mar 30 02:37:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 02:37:09 +0200 (CEST) Subject: [pypy-svn] r73154 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100330003709.DFED5282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 02:37:07 2010 New Revision: 73154 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Build two exceptions differently to make them RPython. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 30 02:37:07 2010 @@ -351,7 +351,10 @@ if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str): return force_string(space, ref) else: - raise InvalidPointerException("Got invalid reference to a PyObject: %r" % (ref, )) + msg = "" + if not we_are_translated(): + msg = "Got invalid reference to a PyObject: %r" % (ref, ) + raise InvalidPointerException(msg) return obj @@ -431,8 +434,8 @@ if failed: error_value = callable.api_func.error_value if error_value is CANNOT_FAIL: - raise SystemError("The function %r was not supposed to fail" - % (callable,)) + raise SystemError("The function '%s' was not supposed to fail" + % (callable.__name__,)) return error_value if callable.api_func.restype is PyObject: From benjamin at codespeak.net Tue Mar 30 04:59:58 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 04:59:58 +0200 (CEST) Subject: [pypy-svn] r73155 - in pypy/trunk/pypy: module/__pypy__ objspace/std Message-ID: <20100330025958.6C3A5282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 04:59:54 2010 New Revision: 73155 Modified: pypy/trunk/pypy/module/__pypy__/interp_magic.py pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/typeobject.py Log: store method cache state on a custom object Modified: pypy/trunk/pypy/module/__pypy__/interp_magic.py ============================================================================== --- pypy/trunk/pypy/module/__pypy__/interp_magic.py (original) +++ pypy/trunk/pypy/module/__pypy__/interp_magic.py Tue Mar 30 04:59:54 2010 @@ -1,6 +1,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace from pypy.rlib.objectmodel import we_are_translated +from pypy.objspace.std.typeobject import MethodCache def internal_repr(space, w_object): return space.wrap('%r' % (w_object,)) @@ -24,13 +25,15 @@ """Return a tuple (method_cache_hits, method_cache_misses) for calls to methods with the name.""" assert space.config.objspace.std.withmethodcachecounter - return space.newtuple([space.newint(space.method_cache_hits.get(name, 0)), - space.newint(space.method_cache_misses.get(name, 0)),]) + cache = space.fromcache(MethodCache) + return space.newtuple([space.newint(cache.hits.get(name, 0)), + space.newint(cache.misses.get(name, 0))]) method_cache_counter.unwrap_spec = [ObjSpace, str] def reset_method_cache_counter(space): """Reset the method cache counter to zero for all method names.""" assert space.config.objspace.std.withmethodcachecounter - space.method_cache_misses = {} - space.method_cache_hits = {} + cache = space.fromcache(MethodCache) + cache.misses = {} + cache.hits = {} Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Mar 30 04:59:54 2010 @@ -56,9 +56,6 @@ self._install_multimethods() - if self.config.objspace.std.withmethodcache: - self._setup_method_cache() - # singletons self.w_None = W_NoneObject.w_None self.w_False = W_BoolObject.w_False @@ -90,15 +87,6 @@ def get_builtin_types(self): return self.builtin_types - def _setup_method_cache(self): - SIZE = 1 << self.config.objspace.std.methodcachesizeexp - self.method_cache_versions = [None] * SIZE - self.method_cache_names = [None] * SIZE - self.method_cache_lookup_where = [(None, None)] * SIZE - if self.config.objspace.std.withmethodcachecounter: - self.method_cache_hits = {} - self.method_cache_misses = {} - def _install_multimethods(self): """Install all the MultiMethods into the space instance.""" model.add_extra_comparisons() Modified: pypy/trunk/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/trunk/pypy/objspace/std/typeobject.py (original) +++ pypy/trunk/pypy/objspace/std/typeobject.py Tue Mar 30 04:59:54 2010 @@ -47,6 +47,19 @@ class VersionTag(object): pass +class MethodCache(object): + + def __init__(self, space): + assert space.config.objspace.std.withmethodcache + SIZE = 1 << space.config.objspace.std.methodcachesizeexp + self.versions = [None] * SIZE + self.names = [None] * SIZE + self.lookup_where = [(None, None)] * SIZE + if space.config.objspace.std.withmethodcachecounter: + self.hits = {} + self.misses = {} + + class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef @@ -265,6 +278,7 @@ @purefunction def _pure_lookup_where_with_method_cache(w_self, name, version_tag): space = w_self.space + cache = space.fromcache(MethodCache) SHIFT2 = r_uint.BITS - space.config.objspace.std.methodcachesizeexp SHIFT1 = SHIFT2 - 5 version_tag_as_int = current_object_addr_as_int(version_tag) @@ -281,23 +295,21 @@ # platforms SHIFT2 is really large, and we loose too much information # that way (as shown by failures of the tests that typically have # method names like 'f' who hash to a number that has only ~33 bits). - cached_version_tag = space.method_cache_versions[method_hash] + cached_version_tag = cache.versions[method_hash] if cached_version_tag is version_tag: - cached_name = space.method_cache_names[method_hash] + cached_name = cache.names[method_hash] if cached_name is name: - tup = space.method_cache_lookup_where[method_hash] + tup = cache.lookup_where[method_hash] if space.config.objspace.std.withmethodcachecounter: - space.method_cache_hits[name] = \ - space.method_cache_hits.get(name, 0) + 1 + cache.hits[name] = cache.hits.get(name, 0) + 1 # print "hit", w_self, name return tup tup = w_self._lookup_where_all_typeobjects(name) - space.method_cache_versions[method_hash] = version_tag - space.method_cache_names[method_hash] = name - space.method_cache_lookup_where[method_hash] = tup + cache.versions[method_hash] = version_tag + cache.names[method_hash] = name + cache.lookup_where[method_hash] = tup if space.config.objspace.std.withmethodcachecounter: - space.method_cache_misses[name] = \ - space.method_cache_misses.get(name, 0) + 1 + cache.misses[name] = cache.misses.get(name, 0) + 1 # print "miss", w_self, name return tup From fijal at codespeak.net Tue Mar 30 05:27:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 30 Mar 2010 05:27:03 +0200 (CEST) Subject: [pypy-svn] r73156 - in pypy/trunk/pypy: interpreter module/_weakref module/_weakref/test Message-ID: <20100330032703.4004C282B9D@codespeak.net> Author: fijal Date: Tue Mar 30 05:27:01 2010 New Revision: 73156 Modified: pypy/trunk/pypy/interpreter/executioncontext.py pypy/trunk/pypy/module/_weakref/interp__weakref.py pypy/trunk/pypy/module/_weakref/test/test_weakref.py Log: Try to kill segfault by fighting with uncontrolled calls of app level weakref callback in the middle of compiling assembler (it could segfault pypy other way, but this is the observed way). Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Tue Mar 30 05:27:01 2010 @@ -478,12 +478,17 @@ def __init__(self, space): AsyncAction.__init__(self, space) self.dying_objects_w = [] + self.weakrefs_w = [] self.finalizers_lock_count = 0 def register_dying_object(self, w_obj): self.dying_objects_w.append(w_obj) self.fire() + def register_weakref_callback(self, w_ref): + self.weakrefs_w.append(w_ref) + self.fire() + def perform(self, executioncontext, frame): if self.finalizers_lock_count > 0: return @@ -505,8 +510,16 @@ # finally, this calls the interp-level destructor for the # cases where there is both an app-level and a built-in __del__. w_obj._call_builtin_destructor() - - + pending_w = self.weakrefs_w + self.weakrefs_w = [] + for i in range(len(pending_w)): + w_ref = pending_w[i] + try: + w_ref.activate_callback() + except OperationError, e: + e.write_unraisable(space, 'weakref ', w_obj) + e.clear(space) # break up reference cycles + class FrameTraceAction(AsyncAction): """An action that calls the local trace functions (w_f_trace).""" Modified: pypy/trunk/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/interp__weakref.py Tue Mar 30 05:27:01 2010 @@ -23,7 +23,7 @@ for i in range(len(self.refs_weak) - 1, -1, -1): w_ref = self.refs_weak[i]() if w_ref is not None: - w_ref.activate_callback() + self.space.user_del_action.register_weakref_callback(w_ref) def clear_all_weakrefs(self): """Clear all weakrefs. This is called when an app-level object has Modified: pypy/trunk/pypy/module/_weakref/test/test_weakref.py ============================================================================== --- pypy/trunk/pypy/module/_weakref/test/test_weakref.py (original) +++ pypy/trunk/pypy/module/_weakref/test/test_weakref.py Tue Mar 30 05:27:01 2010 @@ -411,3 +411,15 @@ a = A() assert _weakref.ref(a) == a + + def test_callback_raises(self): + import _weakref, gc + class A(object): + pass + a1 = A() + def callback(ref): + explode + ref1 = _weakref.ref(a1, callback) + del a1 + gc.collect() + assert ref1() is None From fijal at codespeak.net Tue Mar 30 05:34:38 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 30 Mar 2010 05:34:38 +0200 (CEST) Subject: [pypy-svn] r73157 - pypy/trunk/pypy/interpreter Message-ID: <20100330033438.87346282B9D@codespeak.net> Author: fijal Date: Tue Mar 30 05:34:36 2010 New Revision: 73157 Modified: pypy/trunk/pypy/interpreter/executioncontext.py Log: Kill unreachable code (that has name errors innit) Modified: pypy/trunk/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/trunk/pypy/interpreter/executioncontext.py (original) +++ pypy/trunk/pypy/interpreter/executioncontext.py Tue Mar 30 05:34:36 2010 @@ -514,11 +514,7 @@ self.weakrefs_w = [] for i in range(len(pending_w)): w_ref = pending_w[i] - try: - w_ref.activate_callback() - except OperationError, e: - e.write_unraisable(space, 'weakref ', w_obj) - e.clear(space) # break up reference cycles + w_ref.activate_callback() class FrameTraceAction(AsyncAction): """An action that calls the local trace functions (w_f_trace).""" From fijal at codespeak.net Tue Mar 30 06:47:44 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Tue, 30 Mar 2010 06:47:44 +0200 (CEST) Subject: [pypy-svn] r73158 - pypy/trunk/pypy/tool Message-ID: <20100330044744.2D4AA282B9D@codespeak.net> Author: fijal Date: Tue Mar 30 06:47:42 2010 New Revision: 73158 Modified: pypy/trunk/pypy/tool/terminal.py Log: Provide some defaults if curses is not there Modified: pypy/trunk/pypy/tool/terminal.py ============================================================================== --- pypy/trunk/pypy/tool/terminal.py (original) +++ pypy/trunk/pypy/tool/terminal.py Tue Mar 30 06:47:42 2010 @@ -25,8 +25,8 @@ # List of numeric capabilities VALUES = { - 'COLUMNS':'cols', # Width of the terminal (None for unknown) - 'LINES':'lines', # Height of the terminal (None for unknown) + 'COLUMNS':'cols', # Width of the terminal (80 for unknown) + 'LINES':'lines', # Height of the terminal (25 for unknown) 'MAX_COLORS': 'colors', } @@ -37,8 +37,9 @@ setattr(MODULE, 'BG_%s' % color, '') for control in CONTROLS: setattr(MODULE, control, '') - for value in VALUES: - setattr(MODULE, value, None) + MODULE.COLUMNS = 80 + MODULE.LINES = 25 + MODULE.MAX_COLORS = 1 def setup(): """Set the terminal control strings""" From xoraxax at codespeak.net Tue Mar 30 13:59:24 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 13:59:24 +0200 (CEST) Subject: [pypy-svn] r73159 - in pypy/branch/cpython-extension/pypy: annotation module/cpyext rlib rpython/lltypesystem Message-ID: <20100330115924.E7E1D282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 13:59:22 2010 New Revision: 73159 Modified: pypy/branch/cpython-extension/pypy/annotation/description.py pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/rlib/entrypoint.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py Log: RPythonizing fixes, introduce relax mode that returns a standard graph even if the signature doesnt match. Modified: pypy/branch/cpython-extension/pypy/annotation/description.py ============================================================================== --- pypy/branch/cpython-extension/pypy/annotation/description.py (original) +++ pypy/branch/cpython-extension/pypy/annotation/description.py Tue Mar 30 13:59:22 2010 @@ -209,8 +209,9 @@ if len(self._cache) != 1: raise NoStandardGraph(self) [graph] = self._cache.values() + relax_sig_check = getattr(self.pyobj, "relax_sig_check", False) if (graph.signature != self.signature or - graph.defaults != self.defaults): + graph.defaults != self.defaults) and not relax_sig_check: raise NoStandardGraph(self) return graph Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 30 13:59:22 2010 @@ -102,7 +102,7 @@ def get_llhelper(self, space): llh = getattr(self, '_llhelper', None) if llh is None: - llh = llhelper(self.functype, make_wrapper(space, self.callable)) + llh = llhelper(self.functype, self.get_wrapper(space)) self._llhelper = llh return llh @@ -203,8 +203,9 @@ new_fields = [] for name in T._names: new_fields.append((name, fields[name])) - new_fields.append(("custom_padding", lltype.Array(lltype.Char))) - hints["padding"] = hints["padding"] + ("custom_padding", ) + new_fields.append(("c_custom_padding", lltype.Array(lltype.Char, + hints={'nolength': True}))) + hints["padding"] = hints["padding"] + ("c_custom_padding", ) return lltype.Struct(hints["c_name"], hints=hints, *new_fields) @@ -452,6 +453,7 @@ elif callable.api_func.restype is not lltype.Void: retval = rffi.cast(callable.api_func.restype, retval) return retval + callable._always_inline_ = True wrapper.__name__ = "wrapper for %r" % (callable, ) return wrapper @@ -597,7 +599,7 @@ def setup_library(space): for name, func in FUNCTIONS.iteritems(): - deco = entrypoint("cpyext", func.argtypes, name) + deco = entrypoint("cpyext", func.argtypes, name, relax=True) deco(func.get_wrapper(space)) @unwrap_spec(ObjSpace, str, str) Modified: pypy/branch/cpython-extension/pypy/rlib/entrypoint.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/entrypoint.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/entrypoint.py Tue Mar 30 13:59:22 2010 @@ -1,11 +1,13 @@ secondary_entrypoints = {} -def entrypoint(key, argtypes, c_name=None): +def entrypoint(key, argtypes, c_name=None, relax=False): def deco(func): secondary_entrypoints.setdefault(key, []).append((func, argtypes)) if c_name is not None: func.c_name = c_name + if relax: + func.relax_sig_check = True return func return deco Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py Tue Mar 30 13:59:22 2010 @@ -381,6 +381,7 @@ r_int_real = rarithmetic.build_int("r_int_real", r_int.SIGN, r_int.BITS, True) INT_real = lltype.build_number("INT", r_int_real) platform.numbertype_to_rclass[INT_real] = r_int_real +NUMBER_TYPES.append(INT_real) # ^^^ this creates at least the following names: # -------------------------------------------------------------------- From afa at codespeak.net Tue Mar 30 14:28:15 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 30 Mar 2010 14:28:15 +0200 (CEST) Subject: [pypy-svn] r73160 - in pypy/branch/cpython-extension/pypy/objspace/std: . test Message-ID: <20100330122815.631C7282B9D@codespeak.net> Author: afa Date: Tue Mar 30 14:28:13 2010 New Revision: 73160 Modified: pypy/branch/cpython-extension/pypy/objspace/std/objspace.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_setobject.py Log: Fix space.wrap(set()), which was not tested of course... Modified: pypy/branch/cpython-extension/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/objspace.py Tue Mar 30 14:28:13 2010 @@ -6,7 +6,7 @@ from pypy.interpreter import function from pypy.interpreter.pyopcode import unrolling_compare_dispatch_table, \ BytecodeCorruption -from pypy.rlib.objectmodel import instantiate +from pypy.rlib.objectmodel import instantiate, r_dict from pypy.rlib.debug import make_sure_not_resized from pypy.interpreter.gateway import PyPyCacheDir from pypy.tool.cache import Cache @@ -423,8 +423,11 @@ return W_ComplexObject(x.real, x.imag) if isinstance(x, set): - wrappeditems = [self.wrap(item) for item in x] - return W_SetObject(self, wrappeditems) + rdict_w = r_dict(self.eq_w, self.hash_w) + for item in x: + rdict_w[self.wrap(item)] = None + res = W_SetObject(self, rdict_w) + return res if isinstance(x, frozenset): wrappeditems = [self.wrap(item) for item in x] Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_setobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_setobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_setobject.py Tue Mar 30 14:28:13 2010 @@ -46,6 +46,8 @@ t = W_SetObject(self.space, None) _initialize_set(self.space, t, self.word) assert self.space.eq_w(s,t) + u = self.space.wrap(set('simsalabim')) + assert self.space.eq_w(s,u) class AppTestAppSetTest: def test_subtype(self): From xoraxax at codespeak.net Tue Mar 30 15:00:42 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 15:00:42 +0200 (CEST) Subject: [pypy-svn] r73161 - pypy/branch/cpython-extension/pypy/annotation/test Message-ID: <20100330130042.3059A282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 15:00:40 2010 New Revision: 73161 Modified: pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py Log: Add test for relax. Modified: pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py ============================================================================== --- pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py (original) +++ pypy/branch/cpython-extension/pypy/annotation/test/test_annrpython.py Tue Mar 30 15:00:40 2010 @@ -3290,6 +3290,15 @@ s = a.build_types(f, [int]) assert s.knowntype is int + def test_relax(self): + def f(*args): + return args[0] + args[1] + f.relax_sig_check = True + def g(x): + return f(x, x - x) + a = self.RPythonAnnotator() + s = a.build_types(g, [int]) + assert a.bookkeeper.getdesc(f).getuniquegraph() def g(n): return [0,1,2,n] From xoraxax at codespeak.net Tue Mar 30 15:30:15 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 15:30:15 +0200 (CEST) Subject: [pypy-svn] r73162 - pypy/branch/cpython-extension/pypy/translator/c/test Message-ID: <20100330133015.A706B282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 15:30:13 2010 New Revision: 73162 Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Log: Failing test that blocks cpyext compilation. Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Tue Mar 30 15:30:13 2010 @@ -385,6 +385,39 @@ fn = compile(f, []) fn(expected_extra_mallocs=1) +def test_recursive_llhelper(): + from pypy.rpython.annlowlevel import llhelper + from pypy.rpython.lltypesystem import lltype + from pypy.rlib.objectmodel import specialize + from pypy.rlib.nonconst import NonConstant + FTPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) + class A: + def __init__(self, func): + self.func = func + def _freeze_(self): + return True + @specialize.memo() + def get_llhelper(self): + return llhelper(FTPTR, lambda x: self.func(x)) + STRUCT = lltype.Struct("foo", ("bar", FTPTR)) + def f(s): + if s.bar == a_f.get_llhelper(): + return 1 + return 0 + def g(x): + return 42 + def chooser(x): + s = lltype.malloc(STRUCT, flavor="raw") + if x: + s.bar = a_f.get_llhelper() + else: + s.bar = a_g.get_llhelper() + return f(s) + a_f = A(f) + a_g = A(g) + fn = compile(chooser, [bool]) + assert fn(True) + def test_name(): def f(): return 3 From benjamin at codespeak.net Tue Mar 30 15:55:09 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 15:55:09 +0200 (CEST) Subject: [pypy-svn] r73163 - in pypy/trunk/pypy/objspace/std: . test Message-ID: <20100330135509.760D7282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 15:55:07 2010 New Revision: 73163 Modified: pypy/trunk/pypy/objspace/std/dicttype.py pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py Log: must invoke __new__ of a dict subclass in fromkeys Modified: pypy/trunk/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/pypy/objspace/std/dicttype.py Tue Mar 30 15:55:07 2010 @@ -145,7 +145,7 @@ from pypy.objspace.std.dictmultiobject import W_DictMultiObject if w_fill is None: w_fill = space.w_None - w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type) + w_dict = space.call_function(w_type) w_iter = space.iter(w_keys) while True: try: 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 Tue Mar 30 15:55:07 2010 @@ -372,6 +372,12 @@ assert {}.fromkeys([]) == {} assert {1: 0, 2: 0, 3: 0}.fromkeys([1, '1'], 'j') == ( {1: 'j', '1': 'j'}) + class D(dict): + def __new__(cls): + return E() + class E(dict): + pass + assert isinstance(D.fromkeys([1, 2]), E) def test_str_uses_repr(self): class D(dict): From benjamin at codespeak.net Tue Mar 30 15:57:45 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 15:57:45 +0200 (CEST) Subject: [pypy-svn] r73164 - pypy/trunk/pypy/objspace/std Message-ID: <20100330135745.7BB27282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 15:57:43 2010 New Revision: 73164 Modified: pypy/trunk/pypy/objspace/std/dicttype.py Log: kill import Modified: pypy/trunk/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/trunk/pypy/objspace/std/dicttype.py (original) +++ pypy/trunk/pypy/objspace/std/dicttype.py Tue Mar 30 15:57:43 2010 @@ -142,7 +142,6 @@ @gateway.unwrap_spec(ObjSpace, W_Root, W_Root, W_Root) def descr_fromkeys(space, w_type, w_keys, w_fill=None): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject if w_fill is None: w_fill = space.w_None w_dict = space.call_function(w_type) From benjamin at codespeak.net Tue Mar 30 16:17:37 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 16:17:37 +0200 (CEST) Subject: [pypy-svn] r73165 - pypy/trunk/pypy/rlib Message-ID: <20100330141737.7A886282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 16:17:35 2010 New Revision: 73165 Modified: pypy/trunk/pypy/rlib/rstackovf.py Log: CPython can sometimes raise an AttributeError in recursion situations Modified: pypy/trunk/pypy/rlib/rstackovf.py ============================================================================== --- pypy/trunk/pypy/rlib/rstackovf.py (original) +++ pypy/trunk/pypy/rlib/rstackovf.py Tue Mar 30 16:17:35 2010 @@ -13,7 +13,7 @@ _StackOverflow = StackOverflow # replace StackOverflow with this, which works in untranslated code too -StackOverflow = ((RuntimeError, RuntimeError),) +StackOverflow = ((RuntimeError, AttributeError),) def check_stack_overflow(e): From cfbolz at codespeak.net Tue Mar 30 16:18:37 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Mar 2010 16:18:37 +0200 (CEST) Subject: [pypy-svn] r73166 - in pypy/trunk/pypy/objspace: . test Message-ID: <20100330141837.C46CE282B9D@codespeak.net> Author: cfbolz Date: Tue Mar 30 16:18:36 2010 New Revision: 73166 Modified: pypy/trunk/pypy/objspace/descroperation.py pypy/trunk/pypy/objspace/test/test_descroperation.py Log: issue516 resolved (Antoine Pitrou) Fix special method choice algorithm for old-style classes Modified: pypy/trunk/pypy/objspace/descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/descroperation.py (original) +++ pypy/trunk/pypy/objspace/descroperation.py Tue Mar 30 16:18:36 2010 @@ -5,6 +5,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import default_identity_hash from pypy.tool.sourcetools import compile2, func_with_new_name +from pypy.module.__builtin__.interp_classobj import W_InstanceObject def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -32,6 +33,17 @@ "'%s' object attribute '%s' is read-only", typename, name) +# Helpers for old-style and mix-style mixup + +def _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): + if (space.is_oldstyle_instance(w_obj1) and + space.is_oldstyle_instance(w_obj2)): + assert isinstance(w_obj1, W_InstanceObject) + assert isinstance(w_obj2, W_InstanceObject) + return space.is_w(w_obj1.w_class, w_obj2.w_class) + return space.is_w(w_typ1, w_typ2) + + class Object: def descr__getattribute__(space, w_obj, w_name): name = space.str_w(w_name) @@ -297,7 +309,7 @@ w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, '__pow__') - if space.is_w(w_typ1, w_typ2): + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, '__rpow__') @@ -581,7 +593,7 @@ w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) - if space.is_w(w_typ1, w_typ2): + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, right) @@ -604,8 +616,8 @@ # -- end of bug compatibility if space.is_true(space.issubtype(w_typ2, w_typ1)): if (w_left_src and w_right_src and - not space.abstract_issubclass_w(w_left_src, w_right_src) and - not space.abstract_issubclass_w(w_typ1, w_right_src)): + not space.abstract_issubclass_w(w_left_src, w_right_src) and + not space.abstract_issubclass_w(w_typ1, w_right_src)): w_obj1, w_obj2 = w_obj2, w_obj1 w_left_impl, w_right_impl = w_right_impl, w_left_impl @@ -632,8 +644,8 @@ w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) w_first = w_obj1 w_second = w_obj2 - - if space.is_w(w_typ1, w_typ2): + + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, right) Modified: pypy/trunk/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/trunk/pypy/objspace/test/test_descroperation.py (original) +++ pypy/trunk/pypy/objspace/test/test_descroperation.py Tue Mar 30 16:18:36 2010 @@ -22,82 +22,92 @@ cls.space = conftest.gettestobjspace(**cls.OPTIONS) def test_special_methods(self): - class A(object): - def __lt__(self, other): - return "lt" - def __imul__(self, other): - return "imul" - def __sub__(self, other): - return "sub" - def __rsub__(self, other): - return "rsub" - def __pow__(self, other): - return "pow" - def __rpow__(self, other): - return "rpow" - def __neg__(self): - return "neg" - a = A() - assert (a < 5) == "lt" - assert (object() > a) == "lt" - a1 = a - a1 *= 4 - assert a1 == "imul" - assert a - 2 == "sub" - assert a - object() == "sub" - assert 2 - a == "rsub" - assert object() - a == "rsub" - assert a ** 2 == "pow" - assert a ** object() == "pow" - assert 2 ** a == "rpow" - assert object() ** a == "rpow" - assert -a == "neg" - - class B(A): - def __lt__(self, other): - return "B's lt" - def __imul__(self, other): - return "B's imul" - def __sub__(self, other): - return "B's sub" - def __rsub__(self, other): - return "B's rsub" - def __pow__(self, other): - return "B's pow" - def __rpow__(self, other): - return "B's rpow" - def __neg__(self): - return "B's neg" - - b = B() - assert (a < b) == "lt" - assert (b > a) == "lt" - b1 = b - b1 *= a - assert b1 == "B's imul" - a1 = a - a1 *= b - assert a1 == "imul" - assert a - b == "B's rsub" - assert b - a == "B's sub" - assert b - b == "B's sub" - assert a ** b == "B's rpow" - assert b ** a == "B's pow" - assert b ** b == "B's pow" - assert -b == "B's neg" - - class C(B): + class OldStyle: pass - c = C() - assert c - 1 == "B's sub" - assert 1 - c == "B's rsub" - assert c - b == "B's sub" - assert b - c == "B's sub" - - assert c ** 1 == "B's pow" - assert 1 ** c == "B's rpow" - assert c ** b == "B's pow" - assert b ** c == "B's pow" + for base in (object, OldStyle,): + class A(base): + def __lt__(self, other): + return "lt" + def __imul__(self, other): + return "imul" + def __sub__(self, other): + return "sub" + def __rsub__(self, other): + return "rsub" + def __pow__(self, other): + return "pow" + def __rpow__(self, other): + return "rpow" + def __neg__(self): + return "neg" + a = A() + assert (a < 5) == "lt" + assert (object() > a) == "lt" + a1 = a + a1 *= 4 + assert a1 == "imul" + assert a - 2 == "sub" + assert a - object() == "sub" + assert 2 - a == "rsub" + assert object() - a == "rsub" + assert a ** 2 == "pow" + assert a ** object() == "pow" + assert 2 ** a == "rpow" + assert object() ** a == "rpow" + assert -a == "neg" + + class B(A): + def __lt__(self, other): + return "B's lt" + def __imul__(self, other): + return "B's imul" + def __sub__(self, other): + return "B's sub" + def __rsub__(self, other): + return "B's rsub" + def __pow__(self, other): + return "B's pow" + def __rpow__(self, other): + return "B's rpow" + def __neg__(self): + return "B's neg" + + b = B() + assert (a < b) == "lt" + assert (b > a) == "lt" + b1 = b + b1 *= a + assert b1 == "B's imul" + a1 = a + a1 *= b + assert a1 == "imul" + + if base is object: + assert a - b == "B's rsub" + else: + assert a - b == "sub" + assert b - a == "B's sub" + assert b - b == "B's sub" + if base is object: + assert a ** b == "B's rpow" + else: + assert a ** b == "pow" + assert b ** a == "B's pow" + assert b ** b == "B's pow" + assert -b == "B's neg" + + class C(B): + pass + c = C() + assert c - 1 == "B's sub" + assert 1 - c == "B's rsub" + assert c - b == "B's sub" + assert b - c == "B's sub" + + assert c ** 1 == "B's pow" + assert 1 ** c == "B's rpow" + assert c ** b == "B's pow" + assert b ** c == "B's pow" def test_getslice(self): class Sq(object): @@ -371,6 +381,74 @@ A() < B() assert l == [B, A, A, B] + def test_rich_comparison(self): + # Old-style + class A: + def __init__(self, a): + self.a = a + def __eq__(self, other): + return self.a == other.a + class B: + def __init__(self, a): + self.a = a + # New-style + class C(object): + def __init__(self, a): + self.a = a + def __eq__(self, other): + return self.a == other.a + class D(object): + def __init__(self, a): + self.a = a + + assert A(1) == B(1) + assert B(1) == A(1) + assert A(1) == C(1) + assert C(1) == A(1) + assert A(1) == D(1) + assert D(1) == A(1) + assert C(1) == D(1) + assert D(1) == C(1) + assert not(A(1) == B(2)) + assert not(B(1) == A(2)) + assert not(A(1) == C(2)) + assert not(C(1) == A(2)) + assert not(A(1) == D(2)) + assert not(D(1) == A(2)) + assert not(C(1) == D(2)) + assert not(D(1) == C(2)) + + def test_addition(self): + # Old-style + class A: + def __init__(self, a): + self.a = a + def __add__(self, other): + return self.a + other.a + __radd__ = __add__ + class B: + def __init__(self, a): + self.a = a + # New-style + class C(object): + def __init__(self, a): + self.a = a + def __add__(self, other): + return self.a + other.a + __radd__ = __add__ + class D(object): + def __init__(self, a): + self.a = a + + assert A(1) + B(2) == 3 + assert B(1) + A(2) == 3 + assert A(1) + C(2) == 3 + assert C(1) + A(2) == 3 + assert A(1) + D(2) == 3 + assert D(1) + A(2) == 3 + assert C(1) + D(2) == 3 + assert D(1) + C(2) == 3 + def test_mod_failure(self): try: [] % 3 From benjamin at codespeak.net Tue Mar 30 16:23:56 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 16:23:56 +0200 (CEST) Subject: [pypy-svn] r73167 - pypy/trunk/pypy/rlib Message-ID: <20100330142356.A1CC1282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 16:23:55 2010 New Revision: 73167 Modified: pypy/trunk/pypy/rlib/rstackovf.py Log: accept AttributeError as stack overfow Modified: pypy/trunk/pypy/rlib/rstackovf.py ============================================================================== --- pypy/trunk/pypy/rlib/rstackovf.py (original) +++ pypy/trunk/pypy/rlib/rstackovf.py Tue Mar 30 16:23:55 2010 @@ -21,5 +21,6 @@ return # before translation, an "except StackOverflow" includes all RuntimeErrors, # including NotImplementedError. Special-case them. - if type(e) is not RuntimeError or 'recursion' not in str(e): + if ((type(e) is not RuntimeError or 'recursion' not in str(e)) + and type(e) is not AttributeError): raise e From benjamin at codespeak.net Tue Mar 30 16:35:47 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 16:35:47 +0200 (CEST) Subject: [pypy-svn] r73168 - pypy/trunk/pypy/interpreter Message-ID: <20100330143547.70F80282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 16:35:45 2010 New Revision: 73168 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: add warning Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Tue Mar 30 16:35:45 2010 @@ -108,6 +108,7 @@ next_instr = self.handle_asynchronous_error(ec, self.space.w_MemoryError) except rstackovf.StackOverflow, e: + # Note that this case catches AttributeError! rstackovf.check_stack_overflow(e) next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, From trundle at codespeak.net Tue Mar 30 16:42:32 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Tue, 30 Mar 2010 16:42:32 +0200 (CEST) Subject: [pypy-svn] r73169 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100330144232.648E5282B9D@codespeak.net> Author: trundle Date: Tue Mar 30 16:42:30 2010 New Revision: 73169 Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Log: Return exception type instead of value in PyErr_Occurred(). This makes test_intobject leak somehow. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Tue Mar 30 16:42:30 2010 @@ -14,7 +14,7 @@ def PyErr_Occurred(space): state = space.fromcache(State) register_container(space, lltype.nullptr(PyObject.TO)) - return state.exc_value + return state.exc_type @cpython_api([], lltype.Void) def PyErr_Clear(space): Added: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Tue Mar 30 16:42:30 2010 @@ -0,0 +1,12 @@ +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.rpython.lltypesystem import rffi + +class TestExceptions(BaseApiTest): + def test_Occurred(self, space, api): + assert not api.PyErr_Occurred() + string = rffi.str2charp("spam and eggs") + api.PyErr_SetString(space.w_ValueError, string) + rffi.free_charp(string) + assert api.PyErr_Occurred() is space.w_ValueError + + api.PyErr_Clear() From benjamin at codespeak.net Tue Mar 30 16:44:11 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 16:44:11 +0200 (CEST) Subject: [pypy-svn] r73170 - pypy/trunk/pypy/objspace/std Message-ID: <20100330144411.43CF4282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 16:44:09 2010 New Revision: 73170 Modified: pypy/trunk/pypy/objspace/std/objspace.py Log: try to initialize proxy multimethods early Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Tue Mar 30 16:44:09 2010 @@ -5,7 +5,7 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, - transparent, callmethod) + transparent, callmethod, proxyobject) from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate from pypy.rlib.debug import make_sure_not_resized From xoraxax at codespeak.net Tue Mar 30 16:47:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 16:47:09 +0200 (CEST) Subject: [pypy-svn] r73171 - pypy/branch/cpython-extension/pypy/translator/c/test Message-ID: <20100330144709.5D86D282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 16:47:07 2010 New Revision: 73171 Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Log: Revert r73162, the test was broken - do not use llhelper in Python code. Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Tue Mar 30 16:47:07 2010 @@ -385,39 +385,6 @@ fn = compile(f, []) fn(expected_extra_mallocs=1) -def test_recursive_llhelper(): - from pypy.rpython.annlowlevel import llhelper - from pypy.rpython.lltypesystem import lltype - from pypy.rlib.objectmodel import specialize - from pypy.rlib.nonconst import NonConstant - FTPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) - class A: - def __init__(self, func): - self.func = func - def _freeze_(self): - return True - @specialize.memo() - def get_llhelper(self): - return llhelper(FTPTR, lambda x: self.func(x)) - STRUCT = lltype.Struct("foo", ("bar", FTPTR)) - def f(s): - if s.bar == a_f.get_llhelper(): - return 1 - return 0 - def g(x): - return 42 - def chooser(x): - s = lltype.malloc(STRUCT, flavor="raw") - if x: - s.bar = a_f.get_llhelper() - else: - s.bar = a_g.get_llhelper() - return f(s) - a_f = A(f) - a_g = A(g) - fn = compile(chooser, [bool]) - assert fn(True) - def test_name(): def f(): return 3 From xoraxax at codespeak.net Tue Mar 30 16:47:34 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 16:47:34 +0200 (CEST) Subject: [pypy-svn] r73172 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100330144734.EA041282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 16:47:33 2010 New Revision: 73172 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Log: Rework llhelper usage to RPythonify it. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 30 16:47:33 2010 @@ -98,7 +98,6 @@ def _freeze_(self): return True - @specialize.memo() def get_llhelper(self, space): llh = getattr(self, '_llhelper', None) if llh is None: @@ -106,6 +105,7 @@ self._llhelper = llh return llh + @specialize.memo() def get_wrapper(self, space): wrapper = getattr(self, '_wrapper', None) if wrapper is None: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Tue Mar 30 16:47:33 2010 @@ -118,7 +118,8 @@ pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) assert pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE base = pto - this_func_ptr = subtype_dealloc.api_func.get_llhelper(space) + this_func_ptr = llhelper(subtype_dealloc.api_func.functype, + subtype_dealloc.api_func.get_wrapper(space)) ref_of_object_type = rffi.cast(PyTypeObjectPtr, make_ref(space, space.w_object, steal=True)) while base.c_tp_dealloc == this_func_ptr: @@ -174,15 +175,20 @@ state.py_objects_w2r[w_type] = rffi.cast(PyObject, pto) if space.is_w(w_type, space.w_object): - pto.c_tp_dealloc = PyObject_dealloc.api_func.get_llhelper(space) + pto.c_tp_dealloc = llhelper(PyObject_dealloc.api_func.functype, + PyObject_dealloc.api_func.get_wrapper(space)) elif space.is_w(w_type, space.w_type): - pto.c_tp_dealloc = type_dealloc.api_func.get_llhelper(space) + pto.c_tp_dealloc = llhelper(type_dealloc.api_func.functype, + type_dealloc.api_func.get_wrapper(space)) elif space.is_w(w_type, space.w_str): - pto.c_tp_dealloc = string_dealloc.api_func.get_llhelper(space) + pto.c_tp_dealloc = llhelper(string_dealloc.api_func.functype, + string_dealloc.api_func.get_wrapper(space)) else: - pto.c_tp_dealloc = subtype_dealloc.api_func.get_llhelper(space) + pto.c_tp_dealloc = llhelper(subtype_dealloc.api_func.functype, + subtype_dealloc.api_func.get_wrapper(space)) pto.c_tp_flags = Py_TPFLAGS_HEAPTYPE - pto.c_tp_free = PyObject_Del.api_func.get_llhelper(space) + pto.c_tp_free = llhelper(PyObject_Del.api_func.functype, + PyObject_Del.api_func.get_wrapper(space)) pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?")) pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out pto.c_tp_itemsize = 0 From benjamin at codespeak.net Tue Mar 30 16:54:35 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 16:54:35 +0200 (CEST) Subject: [pypy-svn] r73173 - in pypy/trunk/pypy/interpreter: pyparser pyparser/test test Message-ID: <20100330145435.104E1282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 16:54:33 2010 New Revision: 73173 Modified: pypy/trunk/pypy/interpreter/pyparser/future.py pypy/trunk/pypy/interpreter/pyparser/test/test_futureautomaton.py pypy/trunk/pypy/interpreter/test/test_syntax.py Log: handle future imports after raw or unicode docstrings (issue 515) Modified: pypy/trunk/pypy/interpreter/pyparser/future.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/future.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/future.py Tue Mar 30 16:54:33 2010 @@ -62,7 +62,7 @@ not recognized as a valid future statement or something that may precede a future statement. """ - + def __init__(self, future_flags, string): self.future_flags = future_flags self.s = string @@ -83,7 +83,7 @@ def start(self): c = self.getc() - if c in ["'", '"'] and not self.docstring_consumed: + if c in ("'", '"', "r", "u") and not self.docstring_consumed: self.consume_docstring() elif c in whitespace_or_newline: self.consume_empty_line() @@ -100,6 +100,10 @@ def consume_docstring(self): self.docstring_consumed = True + if self.getc() == "r": + self.pos += 1 + if self.getc() == "u": + self.pos += 1 endchar = self.getc() if (self.getc() == self.getc(+1) and self.getc() == self.getc(+2)): Modified: pypy/trunk/pypy/interpreter/pyparser/test/test_futureautomaton.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyparser/test/test_futureautomaton.py (original) +++ pypy/trunk/pypy/interpreter/pyparser/test/test_futureautomaton.py Tue Mar 30 16:54:33 2010 @@ -150,3 +150,20 @@ assert f.flags == fut.CO_FUTURE_ABSOLUTE_IMPORT +def test_raw_doc(): + s = 'r"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT + +def test_unicode_doc(): + s = 'u"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT + +def test_raw_unicode_doc(): + s = 'ru"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT 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 Tue Mar 30 16:54:33 2010 @@ -359,6 +359,22 @@ exec s assert acontext.calls == '__enter__ __exit__'.split() + def test_raw_doc_string(self): + s = """r'doc' +from __future__ import with_statement +class Context(object): + def __enter__(self): + global enter + enter = True + def __exit__(self, *exc): + global exit + exit = True +with Context() as w: + pass""" + exec s + assert enter + assert exit + def test_with_as_var(self): s = """from __future__ import with_statement From xoraxax at codespeak.net Tue Mar 30 16:55:39 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 16:55:39 +0200 (CEST) Subject: [pypy-svn] r73174 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100330145539.05B4E282B9D@codespeak.net> Author: xoraxax Date: Tue Mar 30 16:55:38 2010 New Revision: 73174 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: Remove padded type hack and just allocate a char array. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 30 16:55:38 2010 @@ -195,19 +195,6 @@ def decorate(func): FUNCTIONS_C[func.func_name] = None return decorate -def get_padded_type(T): - fields = T._flds.copy() - hints = T._hints.copy() - del hints["fieldoffsets"] - pad_fields = [] - new_fields = [] - for name in T._names: - new_fields.append((name, fields[name])) - new_fields.append(("c_custom_padding", lltype.Array(lltype.Char, - hints={'nolength': True}))) - hints["padding"] = hints["padding"] + ("c_custom_padding", ) - return lltype.Struct(hints["c_name"], hints=hints, *new_fields) - def cpython_struct(name, fields, forward=None): configname = name.replace(' ', '__') @@ -239,7 +226,6 @@ PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyObject)) PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), ) cpython_struct('struct _object', PyObjectFields, PyObjectStruct) -PyObjectStructPadded = lltype.ForwardReference() PyStringObjectStruct = lltype.ForwardReference() PyStringObject = lltype.Ptr(PyStringObjectStruct) @@ -251,7 +237,6 @@ for name, TYPE in rffi_platform.configure(CConfig).iteritems(): if name in TYPES: TYPES[name].become(TYPE) - PyObjectStructPadded.become(get_padded_type(PyObjectStruct)) class NullPointerException(Exception): @@ -292,7 +277,7 @@ # Don't increase refcount for non-heaptypes # Py_INCREF(space, pto) basicsize = pto.c_tp_basicsize - py_obj_pad = lltype.malloc(PyObjectStructPadded, basicsize, + py_obj_pad = lltype.malloc(rffi.VOIDP.TO, basicsize, flavor="raw", zero=True) py_obj = rffi.cast(PyObject, py_obj_pad) py_obj.c_ob_refcnt = 1 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 30 16:55:38 2010 @@ -26,8 +26,6 @@ assert 'PyModule_Check' in api.FUNCTIONS assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject] - def test_padding(self): - T = api.get_padded_type(api.PyObject.TO) class AppTestApi: def setup_class(cls): From afa at codespeak.net Tue Mar 30 17:11:23 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 30 Mar 2010 17:11:23 +0200 (CEST) Subject: [pypy-svn] r73175 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100330151123.DD6AB282B9D@codespeak.net> Author: afa Date: Tue Mar 30 17:11:22 2010 New Revision: 73175 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Log: Correctly borrow exc_type with PyErr_Occurred() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Tue Mar 30 17:11:22 2010 @@ -30,10 +30,10 @@ from pypy.module.cpyext.api import make_ref, ADDR # handling of borrowed objects, remove when we have # a weakkeydict - exc_value = make_ref(self.space, self.exc_value, borrowed=True) - if exc_value: - Py_DECREF(self.space, exc_value) - containee_ptr = rffi.cast(ADDR, exc_value) + exc_type = make_ref(self.space, self.exc_type, borrowed=True) + if exc_type: + Py_DECREF(self.space, exc_type) + containee_ptr = rffi.cast(ADDR, exc_type) del self.borrowed_objects[containee_ptr] self.exc_type = None self.exc_value = None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Tue Mar 30 17:11:22 2010 @@ -1,4 +1,5 @@ from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.rpython.lltypesystem import rffi class TestExceptions(BaseApiTest): @@ -10,3 +11,17 @@ assert api.PyErr_Occurred() is space.w_ValueError api.PyErr_Clear() + +class AppTestFetch(AppTestCpythonExtensionBase): + def test_occurred(self): + module = self.import_extension('foo', [ + ("check_error", "METH_NOARGS", + ''' + PyErr_SetString(PyExc_TypeError, "message"); + PyErr_Occurred(); + PyErr_Clear(); + Py_RETURN_TRUE; + ''' + ), + ]) + module.check_error() From arigo at codespeak.net Tue Mar 30 17:16:27 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Mar 2010 17:16:27 +0200 (CEST) Subject: [pypy-svn] r73176 - pypy/trunk/pypy/interpreter Message-ID: <20100330151627.AEA6F282B9D@codespeak.net> Author: arigo Date: Tue Mar 30 17:16:26 2010 New Revision: 73176 Modified: pypy/trunk/pypy/interpreter/gateway.py Log: If we are not translated, use a plain "raise" to propgate the traceback information. Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Tue Mar 30 17:16:26 2010 @@ -23,6 +23,7 @@ from pypy.tool.sourcetools import NiceCompile, compile2 from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint from pypy.rlib import rstackovf +from pypy.rlib.objectmodel import we_are_translated # internal non-translatable parts: import py @@ -564,6 +565,8 @@ def handle_exception(self, space, e): try: + if not we_are_translated(): + raise raise e except KeyboardInterrupt: raise OperationError(space.w_KeyboardInterrupt, From cfbolz at codespeak.net Tue Mar 30 17:38:51 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Mar 2010 17:38:51 +0200 (CEST) Subject: [pypy-svn] r73177 - in pypy/branch/reduce-instance-size-experiments/pypy: config objspace/std objspace/std/test Message-ID: <20100330153851.5801D282B9D@codespeak.net> Author: cfbolz Date: Tue Mar 30 17:38:49 2010 New Revision: 73177 Modified: pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py Log: make inlinedict work only with the sharing dict (which is the sanest combination anyway) Modified: pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/config/pypyoption.py Tue Mar 30 17:38:49 2010 @@ -237,7 +237,8 @@ BoolOption("withinlineddict", "make instances more compact by revoming a level of indirection", default=False, - requires=[("objspace.std.withshadowtracking", False)]), + requires=[("objspace.std.withsharingdict", True), + ("objspace.std.withshadowtracking", False)]), BoolOption("withrangelist", "enable special range list implementation that does not " Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py Tue Mar 30 17:38:49 2010 @@ -7,11 +7,9 @@ from pypy.tool.sourcetools import func_with_new_name def make_mixin(config): - if config.objspace.std.withsharingdict: - from pypy.objspace.std.sharingdict import SharedDictImplementation - return make_inlinedict_mixin(SharedDictImplementation, "structure") - else: - return make_inlinedict_mixin(StrDictImplementation, "content") + assert config.objspace.std.withsharingdict + from pypy.objspace.std.sharingdict import SharedDictImplementation + return make_inlinedict_mixin(SharedDictImplementation, "structure") def make_indirection_method(methname, numargs): # *args don't work, the call normalization gets confused Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py Tue Mar 30 17:38:49 2010 @@ -155,5 +155,6 @@ return a """) assert w_a.w__dict__ is None - assert self.space.int_w(w_a.content['x']) == 12 - assert self.space.int_w(w_a.content['y']) == 13 + assert self.space.int_w(w_a.entries[0]) == 12 + assert self.space.int_w(w_a.entries[1]) == 13 + assert w_a.w__dict__ is None From cfbolz at codespeak.net Tue Mar 30 17:42:17 2010 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Mar 2010 17:42:17 +0200 (CEST) Subject: [pypy-svn] r73178 - in pypy/branch/reduce-instance-size-experiments/pypy/objspace/std: . test Message-ID: <20100330154217.627DF282B9D@codespeak.net> Author: cfbolz Date: Tue Mar 30 17:42:15 2010 New Revision: 73178 Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py Log: some simplifications Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/inlinedict.py Tue Mar 30 17:42:15 2010 @@ -8,8 +8,7 @@ def make_mixin(config): assert config.objspace.std.withsharingdict - from pypy.objspace.std.sharingdict import SharedDictImplementation - return make_inlinedict_mixin(SharedDictImplementation, "structure") + return make_inlinedict_mixin() def make_indirection_method(methname, numargs): # *args don't work, the call normalization gets confused @@ -24,7 +23,9 @@ func.func_defaults = getattr(W_DictMultiObject, methname).func_defaults return func -def make_inlinedict_mixin(dictimplclass, attrname): +def make_inlinedict_mixin(): + from pypy.objspace.std.sharingdict import SharedDictImplementation + dictimplclass = SharedDictImplementation assert dictimplclass.__base__ is W_DictMultiObject class IndirectionIterImplementation(IteratorImplementation): def __init__(self, space, dictimpl, itemlist): @@ -47,8 +48,6 @@ items.append((w_key, w_value)) return IndirectionIterImplementation(self.space, self, items) - IndirectionDictImplementation.__name__ = "IndirectionDictImplementation" + dictimplclass.__name__ - for methname, numargs in implementation_methods: implname = "impl_" + methname if implname != "impl_iter": @@ -69,7 +68,7 @@ self.w__class__ = w_subtype self.w__dict__ = None init_dictattributes(self, space) - assert getattr(self, attrname) is not None + assert self.structure is not None self.user_setup_slots(w_subtype.nslots) def getdict(self): @@ -81,7 +80,7 @@ return w__dict__ def _inlined_dict_valid(self): - return getattr(self, attrname) is not None + return self.structure is not None def getdictvalue(self, space, attr): if self._inlined_dict_valid(): Modified: pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py ============================================================================== --- pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py (original) +++ pypy/branch/reduce-instance-size-experiments/pypy/objspace/std/test/test_inlinedict.py Tue Mar 30 17:42:15 2010 @@ -10,7 +10,7 @@ nslots = 0 class TestMixin(object): - Mixin = make_inlinedict_mixin(StrDictImplementation, "content") + Mixin = make_inlinedict_mixin() class FakeObject(Mixin): def user_setup_slots(self, nslots): pass @@ -114,14 +114,8 @@ assert obj.getdictvalue(self.fakespace, "hello") is None -class TestMixinShared(TestMixin): - Mixin = make_inlinedict_mixin(SharedDictImplementation, "structure") - class FakeObject(Mixin): - def user_setup_slots(self, nslots): - pass - -class TestIndirectDict(BaseTestRDictImplementation): - Mixin = make_inlinedict_mixin(StrDictImplementation, "content") +class TestIndirectDictShared(BaseTestRDictImplementation): + Mixin = make_inlinedict_mixin() class FakeObject(Mixin): def user_setup_slots(self, nslots): pass @@ -132,13 +126,6 @@ return obj.getdict() -class TestIndirectDictShared(TestIndirectDict): - Mixin = make_inlinedict_mixin(SharedDictImplementation, "structure") - class FakeObject(Mixin): - def user_setup_slots(self, nslots): - pass - - class TestInlineDict(object): From benjamin at codespeak.net Tue Mar 30 17:48:32 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 17:48:32 +0200 (CEST) Subject: [pypy-svn] r73179 - pypy/trunk/pypy/rlib/test Message-ID: <20100330154832.6EF2E282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 17:48:30 2010 New Revision: 73179 Modified: pypy/trunk/pypy/rlib/test/test_rstackovf.py Log: add test about cpython raises AttributeError Modified: pypy/trunk/pypy/rlib/test/test_rstackovf.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rstackovf.py (original) +++ pypy/trunk/pypy/rlib/test/test_rstackovf.py Tue Mar 30 17:48:30 2010 @@ -1,4 +1,5 @@ import sys +import py from pypy.rlib import rstackovf def recurse(n): @@ -18,6 +19,21 @@ def test_direct(): assert f(sys.maxint) == 1 +class RecurseGetAttr(object): + + def __getattr__(self, attr): + return getattr(self, attr) + +def test_raises_AttributeError(): + rga = RecurseGetAttr() + try: + rga.y + except AttributeError: + pass + else: + py.test.skip("interpreter is not badly behaved") + py.test.raises(rstackovf.StackOverflow, getattr, rga, "y") + def test_llinterp(): from pypy.rpython.test.test_llinterp import interpret res = interpret(f, [sys.maxint]) From afa at codespeak.net Tue Mar 30 17:48:51 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 30 Mar 2010 17:48:51 +0200 (CEST) Subject: [pypy-svn] r73180 - pypy/branch/cpython-extension/pypy/module/cpyext/test Message-ID: <20100330154851.69245282B9D@codespeak.net> Author: afa Date: Tue Mar 30 17:48:49 2010 New Revision: 73180 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Log: Smaller and faster tests, written at interp_level Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_boolobject.py Tue Mar 30 17:48:49 2010 @@ -1,46 +1,26 @@ from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from pypy.module.cpyext.test.test_api import BaseApiTest -import py -import sys +class TestBoolObject(BaseApiTest): + def test_fromlong(self, space, api): + for i in range(-3, 3): + obj = api.PyBool_FromLong(i) + if i: + assert obj is space.w_True + else: + assert obj is space.w_False -class AppTestBoolObject(AppTestCpythonExtensionBase): - def test_boolobject(self): + def test_check(self, space, api): + assert api.PyBool_Check(space.w_True) + assert api.PyBool_Check(space.w_False) + assert not api.PyBool_Check(space.w_None) + assert not api.PyBool_Check(api.PyFloat_FromDouble(1.0)) + +class AppTestBoolMacros(AppTestCpythonExtensionBase): + def test_macros(self): module = self.import_extension('foo', [ ("get_true", "METH_NOARGS", "Py_RETURN_TRUE;"), ("get_false", "METH_NOARGS", "Py_RETURN_FALSE;"), - ("test_FromLong", "METH_NOARGS", - """ - int i; - for(i=-3; i<3; i++) - { - PyObject* obj = PyBool_FromLong(i); - PyObject* expected = (i ? Py_True : Py_False); - - if(obj != expected) - { - Py_DECREF(obj); - Py_RETURN_FALSE; - } - Py_DECREF(obj); - } - Py_RETURN_TRUE; - """), - ("test_Check", "METH_NOARGS", - """ - int result = 0; - PyObject* f = PyFloat_FromDouble(1.0); - - if(PyBool_Check(Py_True) && - PyBool_Check(Py_False) && - !PyBool_Check(f)) - { - result = 1; - } - Py_DECREF(f); - return PyBool_FromLong(result); - """), ]) assert module.get_true() == True assert module.get_false() == False - assert module.test_FromLong() == True - assert module.test_Check() == True Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Tue Mar 30 17:48:49 2010 @@ -1,40 +1,23 @@ -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +from pypy.module.cpyext.test.test_api import BaseApiTest +class TestDictObject(BaseApiTest): + def test_dict(self, space, api): + d = api.PyDict_New() + assert space.eq_w(d, space.newdict()) -class AppTestDictObject(AppTestCpythonExtensionBase): - def test_dict(self): - module = self.import_extension("foo", [ - ("test_dict_create", "METH_NOARGS", - """ - PyObject *p = PyDict_New(); - return p; - """), - ("test_dict_getitem", "METH_VARARGS", - """ - return PyDict_GetItem(PyTuple_GetItem(args, 0), PyTuple_GetItem(args, 1)); - """), - ("test_dict_setitem", "METH_VARARGS", - """ - PyDict_SetItem( - PyTuple_GetItem(args, 0), - PyTuple_GetItem(args, 1), - PyTuple_GetItem(args, 2) - ); - Py_RETURN_NONE; - """), - ("dict_getitem_str", "METH_VARARGS", - """ - return PyDict_GetItemString(PyTuple_GetItem(args, 0), "name"); - """ - ), - ]) - - assert module.test_dict_create() == {} - assert module.test_dict_getitem({"a": 72}, "a") == 72 - d = {} - module.test_dict_setitem(d, "c", 72) - assert d["c"] == 72 - d["name"] = 3 - assert module.dict_getitem_str(d) == 3 - del d["name"] - raises(KeyError, module.dict_getitem_str, d) + assert space.eq_w(api.PyDict_GetItem(space.wrap({"a": 72}), + space.wrap("a")), + space.wrap(72)) + + assert api.PyDict_SetItem(d, space.wrap("c"), space.wrap(42)) >= 0 + assert space.eq_w(space.getitem(d, space.wrap("c")), + space.wrap(42)) + + space.setitem(d, space.wrap("name"), space.wrap(3)) + assert space.eq_w(api.PyDict_GetItem(d, space.wrap("name")), + space.wrap(3)) + + space.delitem(d, space.wrap("name")) + assert not api.PyDict_GetItem(d, space.wrap("name")) + assert api.PyErr_Occurred() is space.w_KeyError + api.PyErr_Clear() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_floatobject.py Tue Mar 30 17:48:49 2010 @@ -1,5 +1,4 @@ from pypy.module.cpyext.test.test_api import BaseApiTest -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase class TestFloatObject(BaseApiTest): def test_floatobject(self, space, api): @@ -9,20 +8,11 @@ assert api.PyFloat_AsDouble(space.w_None) == -1 api.PyErr_Clear() -class AppTestFloatObject(AppTestCpythonExtensionBase): - def test_float(self): - module = self.import_extension("foo", [ - ("test_float_coerce", "METH_NOARGS", - """ - return PyNumber_Float(PyTuple_GetItem(args, 0)); - """), - ]) - - assert type(module.test_float_coerce(3)) is float - raises(TypeError, module.test_float_coerce, None) - + def test_coerce(self, space, api): + assert space.type(api.PyNumber_Float(space.wrap(3))) is space.w_float + class Coerce(object): def __float__(self): return 42.5 - - assert module.test_float_coerce(Coerce()) == 42.5 + assert space.eq_w(api.PyNumber_Float(space.wrap(Coerce())), + space.wrap(42.5)) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_intobject.py Tue Mar 30 17:48:49 2010 @@ -1,35 +1,18 @@ +from pypy.module.cpyext.test.test_api import BaseApiTest +import sys -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase - -class AppTestIntObject(AppTestCpythonExtensionBase): - def test_intobject(self): - import sys - module = self.import_extension('foo', [ - ("check_int", "METH_VARARGS", - """ - PyObject* a = PyTuple_GetItem(args, 0); - if (PyInt_Check(a)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; - """), - ("add_one", "METH_VARARGS", - """ - PyObject *a = PyTuple_GetItem(args, 0); - long x = PyInt_AsLong(a); - if (x == -1) { - if (PyErr_Occurred()) { - return NULL; - } - } - return PyInt_FromLong(x + 1); - """ - ) - ]) - assert module.check_int(3) - assert module.check_int(True) - assert not module.check_int((1, 2, 3)) +class TestIntObject(BaseApiTest): + def test_intobject(self, space, api): + assert api.PyInt_Check(space.wrap(3)) + assert api.PyInt_Check(space.w_True) + assert not api.PyInt_Check(space.wrap((1, 2, 3))) for i in [3, -5, -1, -sys.maxint, sys.maxint - 1]: - assert module.add_one(i) == i + 1 - assert type(module.add_one(3)) is int - raises(TypeError, module.add_one, None) + x = api.PyInt_AsLong(space.wrap(i)) + assert x == i + w_x = api.PyInt_FromLong(x + 1) + assert space.type(w_x) is space.w_int + assert space.eq_w(w_x, space.wrap(i + 1)) + + assert api.PyInt_AsLong(space.w_None) == -1 + assert api.PyErr_Occurred() is space.w_TypeError + api.PyErr_Clear() Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_sequence.py Tue Mar 30 17:48:49 2010 @@ -1,41 +1,31 @@ +from pypy.rpython.lltypesystem import rffi, lltype +from pypy.interpreter.error import OperationError +from pypy.module.cpyext.test.test_api import BaseApiTest +from pypy.module.cpyext import sequence +class TestIterator(BaseApiTest): + def test_sequence(self, space, api): + w_t = space.wrap((1, 2, 3, 4)) + assert api.PySequence_Fast(w_t, "message") is w_t + w_l = space.wrap((1, 2, 3, 4)) + assert api.PySequence_Fast(w_l, "message") is w_l -from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase + assert space.int_w(api.PySequence_Fast_GET_ITEM(w_l, 1)) == 2 + assert api.PySequence_Fast_GET_SIZE(w_l) == 4 -class AppTestIterator(AppTestCpythonExtensionBase): - def test_iterator(self): - import sys - module = self.import_extension('foo', [ - ("newiter", "METH_VARARGS", - ''' - return PySequence_Fast(PyTuple_GetItem(args, 0), "message"); - ''' - ), - ("fast_getitem", "METH_VARARGS", - ''' - PyObject *lst = PyTuple_GetItem(args, 0); - long index = PyInt_AsLong(PyTuple_GetItem(args, 1)); - return PySequence_Fast_GET_ITEM(lst, index); - ''' - ), - ("fast_getsize", "METH_VARARGS", - ''' - PyObject *lst = PyTuple_GetItem(args, 0); - return PyInt_FromLong(PySequence_Fast_GET_SIZE(lst)); - ''' - ), - ]) - t = (1, 2, 3, 4) - assert module.newiter(t) is t - l = [1, 2, 3, 4] - assert module.newiter(l) is l - assert isinstance(module.newiter(set([1, 2, 3])), tuple) - assert sorted(module.newiter(set([1, 2, 3]))) == [1, 2, 3] - try: - module.newiter(3) - except TypeError, te: - assert te.args == ("message",) - else: - raise Exception("DID NOT RAISE") - assert module.fast_getitem((1, 2, 3), 1) == 2 - assert module.fast_getsize([1, 2, 3]) == 3 + w_set = space.wrap(set((1, 2, 3, 4))) + w_seq = api.PySequence_Fast(w_set, "message") + assert space.type(w_seq) is space.w_tuple + assert space.int_w(space.len(w_seq)) == 4 + + def test_exception(self, space, api): + message = rffi.str2charp("message") + assert not api.PySequence_Fast(space.wrap(3), message) + assert api.PyErr_Occurred() is space.w_TypeError + api.PyErr_Clear() + + exc = raises(OperationError, sequence.PySequence_Fast, + space, space.wrap(3), message) + assert exc.value.match(space, space.w_TypeError) + assert space.str_w(exc.value.get_w_value(space)) == "message" + rffi.free_charp(message) From arigo at codespeak.net Tue Mar 30 17:59:58 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Mar 2010 17:59:58 +0200 (CEST) Subject: [pypy-svn] r73181 - in pypy/trunk/pypy: interpreter rlib rlib/test rpython Message-ID: <20100330155958.24C6F282B9D@codespeak.net> Author: arigo Date: Tue Mar 30 17:59:56 2010 New Revision: 73181 Modified: pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/pyopcode.py pypy/trunk/pypy/rlib/rstackovf.py pypy/trunk/pypy/rlib/test/test_rstackovf.py pypy/trunk/pypy/rpython/llinterp.py Log: I know this trickery with AttributeError is for module/__builtin__/test/test_builtin, however I could not reproduce the original failure, and it seems like a *very* bad idea to catch random AttributeErrors and report them as "RuntimeError: maximum recursion depth exceeded" on top of py.py or in tests. I suppose that we might fix test_builtin directly if the problem shows up again. Also, remove the argument to check_stack_overflow(). Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Tue Mar 30 17:59:56 2010 @@ -574,7 +574,7 @@ except MemoryError: raise OperationError(space.w_MemoryError, space.w_None) except rstackovf.StackOverflow, e: - rstackovf.check_stack_overflow(e) + rstackovf.check_stack_overflow() raise OperationError(space.w_RuntimeError, space.wrap("maximum recursion depth exceeded")) Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Tue Mar 30 17:59:56 2010 @@ -109,7 +109,7 @@ self.space.w_MemoryError) except rstackovf.StackOverflow, e: # Note that this case catches AttributeError! - rstackovf.check_stack_overflow(e) + rstackovf.check_stack_overflow() next_instr = self.handle_asynchronous_error(ec, self.space.w_RuntimeError, self.space.wrap("maximum recursion depth exceeded")) Modified: pypy/trunk/pypy/rlib/rstackovf.py ============================================================================== --- pypy/trunk/pypy/rlib/rstackovf.py (original) +++ pypy/trunk/pypy/rlib/rstackovf.py Tue Mar 30 17:59:56 2010 @@ -1,3 +1,4 @@ +import sys from pypy.rlib.objectmodel import we_are_translated # RPython raises StackOverflow instead of just RuntimeError when running @@ -13,14 +14,14 @@ _StackOverflow = StackOverflow # replace StackOverflow with this, which works in untranslated code too -StackOverflow = ((RuntimeError, AttributeError),) +StackOverflow = ((RuntimeError, RuntimeError),) -def check_stack_overflow(e): +def check_stack_overflow(): if we_are_translated(): return # before translation, an "except StackOverflow" includes all RuntimeErrors, # including NotImplementedError. Special-case them. - if ((type(e) is not RuntimeError or 'recursion' not in str(e)) - and type(e) is not AttributeError): - raise e + e, v, _ = sys.exc_info() + if e is not RuntimeError or 'recursion' not in str(v): + raise Modified: pypy/trunk/pypy/rlib/test/test_rstackovf.py ============================================================================== --- pypy/trunk/pypy/rlib/test/test_rstackovf.py (original) +++ pypy/trunk/pypy/rlib/test/test_rstackovf.py Tue Mar 30 17:59:56 2010 @@ -25,6 +25,7 @@ return getattr(self, attr) def test_raises_AttributeError(): + py.test.skip("not RPython code...") rga = RecurseGetAttr() try: rga.y Modified: pypy/trunk/pypy/rpython/llinterp.py ============================================================================== --- pypy/trunk/pypy/rpython/llinterp.py (original) +++ pypy/trunk/pypy/rpython/llinterp.py Tue Mar 30 17:59:56 2010 @@ -323,7 +323,7 @@ if not (catch_exception and op is block.operations[-1]): raise except RuntimeError, e: - rstackovf.check_stack_overflow(e) + rstackovf.check_stack_overflow() # xxx fish fish fish for proper etype and evalue to use rtyper = self.llinterpreter.typer bk = rtyper.annotator.bookkeeper From getxsick at codespeak.net Tue Mar 30 18:08:29 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Tue, 30 Mar 2010 18:08:29 +0200 (CEST) Subject: [pypy-svn] r73182 - pypy/build/ubuntu/1.2.0/debian Message-ID: <20100330160829.C671F282B9D@codespeak.net> Author: getxsick Date: Tue Mar 30 18:08:28 2010 New Revision: 73182 Modified: pypy/build/ubuntu/1.2.0/debian/changelog Log: change upstream version convention Modified: pypy/build/ubuntu/1.2.0/debian/changelog ============================================================================== --- pypy/build/ubuntu/1.2.0/debian/changelog (original) +++ pypy/build/ubuntu/1.2.0/debian/changelog Tue Mar 30 18:08:28 2010 @@ -1,3 +1,9 @@ +pypy (1.2.0-ppa1+karmic9) karmic; urgency=low + + * Fix failing tests. + + -- Bartosz Skowron Tue, 30 Mar 2010 18:07:06 +0200 + pypy (1.2.0-4) karmic; urgency=low * Add missing build-depends. From benjamin at codespeak.net Tue Mar 30 18:19:16 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 18:19:16 +0200 (CEST) Subject: [pypy-svn] r73183 - pypy/trunk/pypy/interpreter Message-ID: <20100330161916.3DC44282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 18:19:14 2010 New Revision: 73183 Modified: pypy/trunk/pypy/interpreter/baseobjspace.py pypy/trunk/pypy/interpreter/gateway.py pypy/trunk/pypy/interpreter/pyframe.py pypy/trunk/pypy/interpreter/pyopcode.py Log: make the recursion RuntimeError prebuilt Modified: pypy/trunk/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/trunk/pypy/interpreter/baseobjspace.py (original) +++ pypy/trunk/pypy/interpreter/baseobjspace.py Tue Mar 30 18:19:14 2010 @@ -495,6 +495,10 @@ w_exc = self.getitem(w_dic, w_name) exc_types_w[name] = w_exc setattr(self, "w_" + excname, w_exc) + # Make a prebuilt recursion error + w_msg = self.wrap("maximum recursion depth exceeded") + self.prebuilt_recursion_error = OperationError(self.w_RuntimeError, + w_msg) return exc_types_w def install_mixedmodule(self, mixedname, installed_builtin_modules): Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Tue Mar 30 18:19:14 2010 @@ -575,8 +575,7 @@ raise OperationError(space.w_MemoryError, space.w_None) except rstackovf.StackOverflow, e: rstackovf.check_stack_overflow() - raise OperationError(space.w_RuntimeError, - space.wrap("maximum recursion depth exceeded")) + raise space.prebuilt_recursion_error # (verbose) performance hack below Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Tue Mar 30 18:19:14 2010 @@ -64,6 +64,8 @@ self.fastlocals_w = [None]*self.numlocals make_sure_not_resized(self.fastlocals_w) self.f_lineno = code.co_firstlineno + # Keep from having to call space.wrap in a RuntimeError + self._recursion_error = space.wrap("maximum recursion depth exceeded") def append_block(self, block): block.previous = self.lastblock Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Tue Mar 30 18:19:14 2010 @@ -108,11 +108,9 @@ next_instr = self.handle_asynchronous_error(ec, self.space.w_MemoryError) except rstackovf.StackOverflow, e: - # Note that this case catches AttributeError! rstackovf.check_stack_overflow() - next_instr = self.handle_asynchronous_error(ec, - self.space.w_RuntimeError, - self.space.wrap("maximum recursion depth exceeded")) + w_err = self.space.prebuilt_recursion_error + next_instr = self.handle_operation_error(ec, w_err) return next_instr def handle_asynchronous_error(self, ec, w_type, w_value=None): From benjamin at codespeak.net Tue Mar 30 18:36:19 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Tue, 30 Mar 2010 18:36:19 +0200 (CEST) Subject: [pypy-svn] r73184 - pypy/trunk/pypy/tool Message-ID: <20100330163619.2D014282B9D@codespeak.net> Author: benjamin Date: Tue Mar 30 18:36:17 2010 New Revision: 73184 Modified: pypy/trunk/pypy/tool/runsubprocess.py Log: silence popen2 warnings Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Tue Mar 30 18:36:17 2010 @@ -3,7 +3,9 @@ if the current process already grew very large. """ -import sys, os +import sys +import os +import warnings from subprocess import PIPE, Popen def run_subprocess(executable, args, env=None, cwd=None): @@ -44,6 +46,9 @@ # do this at import-time, when the process is still tiny _source = os.path.dirname(os.path.abspath(__file__)) _source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc' + # Let's not hear about os.popen2's deprecation. + warnings.filterwarnings("ignore", "popen2", DeprecationWarning, + "runsubprocess") _child_stdin, _child_stdout = os.popen2( "'%s' '%s'" % (sys.executable, _source)) From lucian at codespeak.net Tue Mar 30 18:54:04 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 30 Mar 2010 18:54:04 +0200 (CEST) Subject: [pypy-svn] r73186 - pypy/branch/port-to-2.7 Message-ID: <20100330165404.8B90B282B9D@codespeak.net> Author: lucian Date: Tue Mar 30 18:54:02 2010 New Revision: 73186 Added: pypy/branch/port-to-2.7/ (props changed) - copied from r73185, pypy/trunk/ Log: Creating 2.7 branch. From lucian at codespeak.net Tue Mar 30 19:07:48 2010 From: lucian at codespeak.net (lucian at codespeak.net) Date: Tue, 30 Mar 2010 19:07:48 +0200 (CEST) Subject: [pypy-svn] r73187 - in pypy/branch: port-to-2.6 port-to-2.7 Message-ID: <20100330170748.C4F47282B9D@codespeak.net> Author: lucian Date: Tue Mar 30 19:07:47 2010 New Revision: 73187 Added: pypy/branch/port-to-2.6/ (props changed) - copied from r73186, pypy/branch/port-to-2.7/ Removed: pypy/branch/port-to-2.7/ Log: Rename branch because milestone changed. From tobami at codespeak.net Tue Mar 30 19:10:24 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Tue, 30 Mar 2010 19:10:24 +0200 (CEST) Subject: [pypy-svn] r73188 - pypy/benchmarks Message-ID: <20100330171024.D77CC282B9D@codespeak.net> Author: tobami Date: Tue Mar 30 19:10:23 2010 New Revision: 73188 Modified: pypy/benchmarks/saveresults.py Log: Save revision branch correctly Modified: pypy/benchmarks/saveresults.py ============================================================================== --- pypy/benchmarks/saveresults.py (original) +++ pypy/benchmarks/saveresults.py Tue Mar 30 19:10:23 2010 @@ -10,9 +10,9 @@ #Parse data data = {} current_date = datetime.today() - if branch != "" and branch != "trunk": - interpreter = branch - int_options = "" + if branch == "": + print("ERROR: No branch defined") + return 1 for b in results: bench_name = b[0] @@ -29,6 +29,7 @@ data = { 'revision_number': revision, 'revision_project': project, + 'revision_branch': branch, 'interpreter_name': interpreter, 'interpreter_coptions': int_options, 'benchmark_name': bench_name, From tobami at codespeak.net Tue Mar 30 19:18:03 2010 From: tobami at codespeak.net (tobami at codespeak.net) Date: Tue, 30 Mar 2010 19:18:03 +0200 (CEST) Subject: [pypy-svn] r73189 - pypy/benchmarks/test Message-ID: <20100330171803.CBDA5282B9D@codespeak.net> Author: tobami Date: Tue Mar 30 19:18:01 2010 New Revision: 73189 Modified: pypy/benchmarks/test/test_saveresults.py Log: Adapt unit test for saveresults.py Modified: pypy/benchmarks/test/test_saveresults.py ============================================================================== --- pypy/benchmarks/test/test_saveresults.py (original) +++ pypy/benchmarks/test/test_saveresults.py Tue Mar 30 19:18:01 2010 @@ -22,9 +22,10 @@ def test_good_input(self): '''Given correct result data, check that every result being saved has the right parameters''' - for resultparams in saveresults.save("pypy", 71212, self.fixture, "", "trunk", "pypy-c-jit", "gc=hybrid", 'host', True): + for resultparams in saveresults.save("pypy", 71212, self.fixture, "", "experimental", "pypy-c-jit", "gc=hybrid", 'host', True): assert resultparams['revision_project'] == "pypy" assert resultparams['revision_number'] == 71212 + assert resultparams['revision_branch'] == "experimental" assert resultparams['interpreter_name'] == "pypy-c-jit" assert resultparams['interpreter_coptions'] == "gc=hybrid" # get dict with correct data for this benchmark From trundle at codespeak.net Tue Mar 30 20:37:54 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Tue, 30 Mar 2010 20:37:54 +0200 (CEST) Subject: [pypy-svn] r73190 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100330183754.5A197282B9D@codespeak.net> Author: trundle Date: Tue Mar 30 20:37:51 2010 New Revision: 73190 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Log: Implement PyErr_GivenExceptionMatches. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Tue Mar 30 20:37:51 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError from pypy.module.cpyext.api import cpython_api, PyObject, make_ref,\ - register_container + register_container, CANNOT_FAIL from pypy.module.cpyext.state import State @cpython_api([PyObject, rffi.CCHARP], lltype.Void) @@ -25,3 +25,15 @@ def PyErr_BadInternalCall(space): raise OperationError(space.w_SystemError, space.wrap("Bad internal call!")) + at cpython_api([PyObject, PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyErr_GivenExceptionMatches(space, w_given, w_exc): + """Return true if the given exception matches the exception in exc. If + exc is a class object, this also returns true when given is an instance + of a subclass. If exc is a tuple, all exceptions in the tuple (and + recursively in subtuples) are searched for a match.""" + if (space.is_true(space.isinstance(w_given, space.w_BaseException)) or + space.is_oldstyle_instance(w_given)): + w_given_type = space.exception_getclass(w_given) + else: + w_given_type = w_given + return space.exception_match(w_given_type, w_exc) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Tue Mar 30 20:37:51 2010 @@ -1523,14 +1523,6 @@ violation will occur if no exception has been raised.""" raise NotImplementedError - at cpython_api([PyObject, PyObject], rffi.INT_real) -def PyErr_GivenExceptionMatches(space, given, exc): - """Return true if the given exception matches the exception in exc. If - exc is a class object, this also returns true when given is an instance - of a subclass. If exc is a tuple, all exceptions in the tuple (and - recursively in subtuples) are searched for a match.""" - raise NotImplementedError - @cpython_api([{PyObject**exc}, {PyObject**val}, {PyObject**tb}], lltype.Void) def PyErr_NormalizeException(space, , , ): """Under certain circumstances, the values returned by PyErr_Fetch() below Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Tue Mar 30 20:37:51 2010 @@ -3,6 +3,29 @@ from pypy.rpython.lltypesystem import rffi class TestExceptions(BaseApiTest): + def test_GivenExceptionMatches(self, space, api): + old_style_exception = space.appexec([], """(): + class OldStyle: + pass + return OldStyle + """) + exc_matches = api.PyErr_GivenExceptionMatches + + string_exception = space.wrap('exception') + instance = space.call_function(space.w_ValueError) + old_style_instance = space.call_function(old_style_exception) + assert exc_matches(string_exception, string_exception) + assert exc_matches(old_style_exception, old_style_exception) + assert not exc_matches(old_style_exception, space.w_Exception) + assert exc_matches(instance, space.w_ValueError) + assert exc_matches(old_style_instance, old_style_exception) + assert exc_matches(space.w_ValueError, space.w_ValueError) + assert exc_matches(space.w_IndexError, space.w_LookupError) + assert not exc_matches(space.w_ValueError, space.w_LookupError) + + exceptions = space.newtuple([space.w_LookupError, space.w_ValueError]) + assert exc_matches(space.w_ValueError, exceptions) + def test_Occurred(self, space, api): assert not api.PyErr_Occurred() string = rffi.str2charp("spam and eggs") From xoraxax at codespeak.net Tue Mar 30 23:55:48 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Mar 2010 23:55:48 +0200 (CEST) Subject: [pypy-svn] r73191 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100330215548.A3FCC282BD6@codespeak.net> Author: xoraxax Date: Tue Mar 30 23:55:45 2010 New Revision: 73191 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c pypy/branch/cpython-extension/pypy/module/cpyext/include/varargwrapper.c pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: Slice build_bridge into small functions. And this time I moved pypy_rename.h again into Python.h and renamed it to pypy_macros.h. The rationale is that a) we do not want to modify extensions to be compilable against PyPy if it is not strictly necessary, b) pypy_macros.h can also be used for other macros like it is already (the dereferencing macros for example). Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Tue Mar 30 23:55:45 2010 @@ -53,6 +53,7 @@ for name in constant_names: setattr(CConfig_constants, name, rffi_platform.ConstantInteger(name)) udir.join('pypy_decl.h').write("/* Will be filled later */") +udir.join('pypy_macros.h').write("/* Will be filled later */") globals().update(rffi_platform.configure(CConfig_constants)) _NOT_SPECIFIED = object() @@ -462,40 +463,14 @@ # back into Pypy space functions # Do not call this more than once per process def build_bridge(space, rename=True): - db = LowLevelDatabase() - export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) + db = LowLevelDatabase() - structindex = {} - - prologue = """\ - #include - #include - """ - pypy_rename = [] - renamed_symbols = [] - for name in export_symbols: - if name.startswith("PyPy"): - renamed_symbols.append(name) - continue - if "#" in name: - deref = "*" - else: - deref = "" - if not rename: continue - name = name.replace("#", "") - newname = name.replace('Py', 'PyPy') - if not rename: - newname = name - pypy_rename.append('#define %s %s%s' % (name, deref, newname)) - renamed_symbols.append(newname) - export_symbols = renamed_symbols - pypy_rename_h = udir.join('pypy_rename.h') - pypy_rename_h.write('\n'.join(pypy_rename)) - + generate_macros(export_symbols, rename) # Structure declaration code members = [] + structindex = {} for name, func in FUNCTIONS.iteritems(): cdecl = db.gettype(func.functype) members.append(cdecl.replace('@', name) + ';') @@ -508,50 +483,21 @@ struct PyPyAPI* pypyAPI = &_pypyAPI; """ % dict(members=structmembers) - # implement function callbacks and generate function decls - functions = [] - pypy_decls = [] - for name, func in sorted(FUNCTIONS.iteritems()): - restype = db.gettype(func.restype).replace('@', '') - args = [] - for i, argtype in enumerate(func.argtypes): - arg = db.gettype(argtype) - arg = arg.replace('@', 'arg%d' % (i,)) - args.append(arg) - args = ', '.join(args) or "void" - callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) - header = "%s %s(%s)" % (restype, name, args) - pypy_decls.append(header + ";") - body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) - functions.append('%s\n%s\n' % (header, body)) - - pypy_decl_h = udir.join('pypy_decl.h') - pypy_decl_h.write('\n'.join(pypy_decls)) + functions = generate_decls_and_callbacks(db) global_objects = [] for name, (type, expr) in GLOBALS.iteritems(): global_objects.append('%s %s = NULL;' % (type, name.replace("#", ""))) global_code = '\n'.join(global_objects) + + prologue = "#include \n" code = (prologue + struct_declaration_code + global_code + '\n' + '\n'.join(functions)) - # Build code and get pointer to the structure - kwds = {} - if sys.platform != "win32": - kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] - - eci = ExternalCompilationInfo( - include_dirs=include_dirs, - separate_module_sources=[code], - separate_module_files=[include_dir / "varargwrapper.c", - include_dir / "pyerrors.c", - include_dir / "modsupport.c"], - export_symbols=['pypyAPI'] + export_symbols, - **kwds - ) + eci = build_eci(True, export_symbols, code) eci = eci.convert_sources_to_files() modulename = platform.platform.compile( [], eci, @@ -559,6 +505,7 @@ standalone=False) bootstrap_types(space) + # load the bridge, and init structure import ctypes bridge = ctypes.CDLL(str(modulename)) @@ -582,11 +529,82 @@ return modulename.new(ext='') +def generate_macros(export_symbols, rename=True): + pypy_macros = [] + renamed_symbols = [] + for name in export_symbols: + if name.startswith("PyPy"): + renamed_symbols.append(name) + continue + if "#" in name: + deref = "*" + else: + deref = "" + if not rename: continue + name = name.replace("#", "") + newname = name.replace('Py', 'PyPy') + if not rename: + newname = name + pypy_macros.append('#define %s %s%s' % (name, deref, newname)) + renamed_symbols.append(newname) + export_symbols = renamed_symbols + pypy_macros_h = udir.join('pypy_macros.h') + pypy_macros_h.write('\n'.join(pypy_macros)) + +def generate_decls_and_callbacks(db): + # implement function callbacks and generate function decls + functions = [] + pypy_decls = [] + for name, func in sorted(FUNCTIONS.iteritems()): + restype = db.gettype(func.restype).replace('@', '') + args = [] + for i, argtype in enumerate(func.argtypes): + arg = db.gettype(argtype) + arg = arg.replace('@', 'arg%d' % (i,)) + args.append(arg) + args = ', '.join(args) or "void" + callargs = ', '.join('arg%d' % (i,) for i in range(len(func.argtypes))) + header = "%s %s(%s)" % (restype, name, args) + pypy_decls.append(header + ";") + body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) + functions.append('%s\n%s\n' % (header, body)) + + pypy_decl_h = udir.join('pypy_decl.h') + pypy_decl_h.write('\n'.join(pypy_decls)) + return functions + +def build_eci(build_bridge, export_symbols, code=None): + # Build code and get pointer to the structure + kwds = {} + export_symbols_eci = export_symbols[:] + + if sys.platform != "win32": + kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] + + if build_bridge: + assert code is not None + kwds["separate_module_sources"] = [code] + export_symbols_eci.append('pypyAPI') + else: + assert code is None + + eci = ExternalCompilationInfo( + include_dirs=include_dirs, + separate_module_files=[include_dir / "varargwrapper.c", + include_dir / "pyerrors.c", + include_dir / "modsupport.c"], + export_symbols=export_symbols, + **kwds + ) + return eci + + def setup_library(space): for name, func in FUNCTIONS.iteritems(): deco = entrypoint("cpyext", func.argtypes, name, relax=True) deco(func.get_wrapper(space)) + @unwrap_spec(ObjSpace, str, str) def load_extension_module(space, path, name): state = space.fromcache(State) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Tue Mar 30 23:55:45 2010 @@ -18,6 +18,8 @@ #endif #define Py_ssize_t long +#include + #include "patchlevel.h" #include "object.h" Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.c Tue Mar 30 23:55:45 2010 @@ -1,4 +1,3 @@ -#include #include #if 0 unsupported functions in it Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.c Tue Mar 30 23:55:45 2010 @@ -1,5 +1,3 @@ - -#include #include #include #if 0 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/varargwrapper.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/varargwrapper.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/varargwrapper.c Tue Mar 30 23:55:45 2010 @@ -1,4 +1,3 @@ -#include #include #include Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/foo.c Tue Mar 30 23:55:45 2010 @@ -1,4 +1,3 @@ -#include "pypy_rename.h" #include "Python.h" typedef struct { Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Tue Mar 30 23:55:45 2010 @@ -57,7 +57,6 @@ def import_module(self, name, init=None, body=''): if init is not None: code = """ - #include #include %(body)s From benjamin at codespeak.net Wed Mar 31 00:17:19 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 00:17:19 +0200 (CEST) Subject: [pypy-svn] r73192 - in pypy/branch/cpython-extension: . dotviewer lib-python pypy pypy/doc pypy/interpreter pypy/interpreter/pyparser pypy/interpreter/pyparser/test pypy/interpreter/test pypy/jit/backend/cli/test pypy/jit/backend/llsupport pypy/jit/backend/llsupport/test pypy/jit/backend/llvm/test pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/backend/x86/tool pypy/jit/metainterp pypy/lib pypy/lib/_ctypes pypy/lib/app_test pypy/lib/app_test/ctypes_tests pypy/module/__pypy__ pypy/module/_file pypy/module/_minimal_curses pypy/module/_socket pypy/module/_socket/test pypy/module/_sre pypy/module/_weakref pypy/module/_weakref/test pypy/module/exceptions pypy/module/imp pypy/module/mmap pypy/module/posix pypy/module/posix/test pypy/module/pyexpat/test pypy/module/pypyjit pypy/module/rctime pypy/module/rctime/test pypy/module/readline/test pypy/module/zipimport pypy/module/zipimport/test pypy/objspace pypy/objspace/flow pypy/objspace/std pypy/objspace/std/test pypy/objspace/test pypy/rlib pypy/rlib/test pypy/rpython pypy/rpython/lltypesystem pypy/rpython/lltypesystem/test pypy/rpython/memory/gc pypy/rpython/memory/gc/test pypy/rpython/memory/test pypy/rpython/test pypy/rpython/tool pypy/rpython/tool/test pypy/tool pypy/tool/test pypy/translator pypy/translator/c pypy/translator/c/gcc/test pypy/translator/c/src pypy/translator/c/test pypy/translator/c/winproj pypy/translator/goal pypy/translator/jvm/test pypy/translator/platform pypy/translator/platform/test pypy/translator/stackless Message-ID: <20100330221719.D113C282BD6@codespeak.net> Author: benjamin Date: Wed Mar 31 00:17:06 2010 New Revision: 73192 Added: pypy/branch/cpython-extension/pypy/jit/backend/llsupport/support.py - copied unchanged from r73191, pypy/trunk/pypy/jit/backend/llsupport/support.py pypy/branch/cpython-extension/pypy/objspace/std/frame.py - copied unchanged from r73191, pypy/trunk/pypy/objspace/std/frame.py pypy/branch/cpython-extension/pypy/rlib/rstackovf.py - copied unchanged from r73191, pypy/trunk/pypy/rlib/rstackovf.py pypy/branch/cpython-extension/pypy/rlib/test/test_rstackovf.py - copied unchanged from r73191, pypy/trunk/pypy/rlib/test/test_rstackovf.py pypy/branch/cpython-extension/pypy/tool/runsubprocess.py - copied unchanged from r73191, pypy/trunk/pypy/tool/runsubprocess.py pypy/branch/cpython-extension/pypy/tool/test/test_runsubprocess.py - copied unchanged from r73191, pypy/trunk/pypy/tool/test/test_runsubprocess.py pypy/branch/cpython-extension/pypy/translator/c/src/winstuff.c - copied unchanged from r73191, pypy/trunk/pypy/translator/c/src/winstuff.c Removed: pypy/branch/cpython-extension/pypy/lib/functional.py pypy/branch/cpython-extension/pypy/objspace/std/mro.py pypy/branch/cpython-extension/pypy/translator/c/winproj/ Modified: pypy/branch/cpython-extension/ (props changed) pypy/branch/cpython-extension/dotviewer/ (props changed) pypy/branch/cpython-extension/lib-python/ (props changed) pypy/branch/cpython-extension/lib-python/conftest.py pypy/branch/cpython-extension/pypy/ (props changed) pypy/branch/cpython-extension/pypy/doc/coding-guide.txt pypy/branch/cpython-extension/pypy/doc/getting-started-python.txt pypy/branch/cpython-extension/pypy/interpreter/baseobjspace.py pypy/branch/cpython-extension/pypy/interpreter/error.py pypy/branch/cpython-extension/pypy/interpreter/executioncontext.py pypy/branch/cpython-extension/pypy/interpreter/gateway.py pypy/branch/cpython-extension/pypy/interpreter/nestedscope.py pypy/branch/cpython-extension/pypy/interpreter/pyframe.py pypy/branch/cpython-extension/pypy/interpreter/pyopcode.py pypy/branch/cpython-extension/pypy/interpreter/pyparser/future.py pypy/branch/cpython-extension/pypy/interpreter/pyparser/test/test_futureautomaton.py pypy/branch/cpython-extension/pypy/interpreter/test/test_executioncontext.py pypy/branch/cpython-extension/pypy/interpreter/test/test_gateway.py pypy/branch/cpython-extension/pypy/interpreter/test/test_interpreter.py pypy/branch/cpython-extension/pypy/interpreter/test/test_syntax.py pypy/branch/cpython-extension/pypy/interpreter/test/test_zpy.py pypy/branch/cpython-extension/pypy/jit/backend/cli/test/conftest.py (props changed) pypy/branch/cpython-extension/pypy/jit/backend/llsupport/descr.py pypy/branch/cpython-extension/pypy/jit/backend/llsupport/gc.py pypy/branch/cpython-extension/pypy/jit/backend/llsupport/llmodel.py pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_descr.py pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_gc.py pypy/branch/cpython-extension/pypy/jit/backend/llvm/test/conftest.py (props changed) pypy/branch/cpython-extension/pypy/jit/backend/x86/assembler.py pypy/branch/cpython-extension/pypy/jit/backend/x86/runner.py pypy/branch/cpython-extension/pypy/jit/backend/x86/test/conftest.py pypy/branch/cpython-extension/pypy/jit/backend/x86/test/test_gc_integration.py (props changed) pypy/branch/cpython-extension/pypy/jit/backend/x86/test/test_ztranslation.py pypy/branch/cpython-extension/pypy/jit/backend/x86/tool/viewcode.py pypy/branch/cpython-extension/pypy/jit/metainterp/logger.py (props changed) pypy/branch/cpython-extension/pypy/lib/_ctypes/function.py pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_cast.py pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_funcptr.py pypy/branch/cpython-extension/pypy/lib/app_test/test_dbm_extra.py pypy/branch/cpython-extension/pypy/lib/resource.py pypy/branch/cpython-extension/pypy/module/__pypy__/interp_magic.py pypy/branch/cpython-extension/pypy/module/_file/__init__.py pypy/branch/cpython-extension/pypy/module/_minimal_curses/__init__.py pypy/branch/cpython-extension/pypy/module/_socket/interp_func.py pypy/branch/cpython-extension/pypy/module/_socket/test/test_sock_app.py pypy/branch/cpython-extension/pypy/module/_sre/interp_sre.py pypy/branch/cpython-extension/pypy/module/_weakref/interp__weakref.py pypy/branch/cpython-extension/pypy/module/_weakref/test/test_weakref.py pypy/branch/cpython-extension/pypy/module/exceptions/ (props changed) pypy/branch/cpython-extension/pypy/module/imp/importing.py pypy/branch/cpython-extension/pypy/module/mmap/interp_mmap.py pypy/branch/cpython-extension/pypy/module/posix/interp_posix.py pypy/branch/cpython-extension/pypy/module/posix/test/test_posix2.py pypy/branch/cpython-extension/pypy/module/pyexpat/test/test_build.py pypy/branch/cpython-extension/pypy/module/pypyjit/interp_jit.py pypy/branch/cpython-extension/pypy/module/rctime/interp_time.py pypy/branch/cpython-extension/pypy/module/rctime/test/test_rctime.py pypy/branch/cpython-extension/pypy/module/readline/test/test_c_readline.py pypy/branch/cpython-extension/pypy/module/readline/test/test_with_pypy.py pypy/branch/cpython-extension/pypy/module/zipimport/interp_zipimport.py pypy/branch/cpython-extension/pypy/module/zipimport/test/test_zipimport.py pypy/branch/cpython-extension/pypy/objspace/descroperation.py pypy/branch/cpython-extension/pypy/objspace/flow/model.py pypy/branch/cpython-extension/pypy/objspace/flow/objspace.py pypy/branch/cpython-extension/pypy/objspace/std/__init__.py pypy/branch/cpython-extension/pypy/objspace/std/boolobject.py pypy/branch/cpython-extension/pypy/objspace/std/booltype.py pypy/branch/cpython-extension/pypy/objspace/std/complexobject.py pypy/branch/cpython-extension/pypy/objspace/std/complextype.py pypy/branch/cpython-extension/pypy/objspace/std/default.py pypy/branch/cpython-extension/pypy/objspace/std/dictmultiobject.py pypy/branch/cpython-extension/pypy/objspace/std/dictproxyobject.py pypy/branch/cpython-extension/pypy/objspace/std/dictproxytype.py pypy/branch/cpython-extension/pypy/objspace/std/dicttype.py pypy/branch/cpython-extension/pypy/objspace/std/floatobject.py pypy/branch/cpython-extension/pypy/objspace/std/floattype.py pypy/branch/cpython-extension/pypy/objspace/std/frozensettype.py pypy/branch/cpython-extension/pypy/objspace/std/intobject.py pypy/branch/cpython-extension/pypy/objspace/std/inttype.py pypy/branch/cpython-extension/pypy/objspace/std/iterobject.py pypy/branch/cpython-extension/pypy/objspace/std/itertype.py pypy/branch/cpython-extension/pypy/objspace/std/listobject.py pypy/branch/cpython-extension/pypy/objspace/std/listtype.py pypy/branch/cpython-extension/pypy/objspace/std/longobject.py pypy/branch/cpython-extension/pypy/objspace/std/longtype.py pypy/branch/cpython-extension/pypy/objspace/std/marshal_impl.py pypy/branch/cpython-extension/pypy/objspace/std/model.py pypy/branch/cpython-extension/pypy/objspace/std/noneobject.py pypy/branch/cpython-extension/pypy/objspace/std/nonetype.py pypy/branch/cpython-extension/pypy/objspace/std/objectobject.py pypy/branch/cpython-extension/pypy/objspace/std/objecttype.py pypy/branch/cpython-extension/pypy/objspace/std/objspace.py pypy/branch/cpython-extension/pypy/objspace/std/proxyobject.py pypy/branch/cpython-extension/pypy/objspace/std/rangeobject.py pypy/branch/cpython-extension/pypy/objspace/std/register_all.py pypy/branch/cpython-extension/pypy/objspace/std/ropeobject.py pypy/branch/cpython-extension/pypy/objspace/std/ropeunicodeobject.py pypy/branch/cpython-extension/pypy/objspace/std/setobject.py pypy/branch/cpython-extension/pypy/objspace/std/settype.py pypy/branch/cpython-extension/pypy/objspace/std/sliceobject.py pypy/branch/cpython-extension/pypy/objspace/std/slicetype.py pypy/branch/cpython-extension/pypy/objspace/std/smallintobject.py pypy/branch/cpython-extension/pypy/objspace/std/stdtypedef.py pypy/branch/cpython-extension/pypy/objspace/std/stringobject.py pypy/branch/cpython-extension/pypy/objspace/std/stringtype.py pypy/branch/cpython-extension/pypy/objspace/std/strjoinobject.py pypy/branch/cpython-extension/pypy/objspace/std/strsliceobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_complexobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_dictmultiobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_floatobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_intobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_listobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_longobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_setobject.py (props changed) pypy/branch/cpython-extension/pypy/objspace/std/test/test_smallintobject.py pypy/branch/cpython-extension/pypy/objspace/std/test/test_typeobject.py pypy/branch/cpython-extension/pypy/objspace/std/transparent.py pypy/branch/cpython-extension/pypy/objspace/std/tupleobject.py pypy/branch/cpython-extension/pypy/objspace/std/tupletype.py pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py pypy/branch/cpython-extension/pypy/objspace/std/typetype.py pypy/branch/cpython-extension/pypy/objspace/std/unicodeobject.py pypy/branch/cpython-extension/pypy/objspace/std/unicodetype.py pypy/branch/cpython-extension/pypy/objspace/test/test_descroperation.py pypy/branch/cpython-extension/pypy/rlib/_rsocket_rffi.py pypy/branch/cpython-extension/pypy/rlib/rarithmetic.py pypy/branch/cpython-extension/pypy/rlib/rbigint.py pypy/branch/cpython-extension/pypy/rlib/rmarshal.py pypy/branch/cpython-extension/pypy/rlib/rsocket.py pypy/branch/cpython-extension/pypy/rlib/rstack.py pypy/branch/cpython-extension/pypy/rlib/rzipfile.py pypy/branch/cpython-extension/pypy/rlib/test/test_rarithmetic.py pypy/branch/cpython-extension/pypy/rlib/test/test_rbigint.py pypy/branch/cpython-extension/pypy/rlib/test/test_rcoroutine.py (props changed) pypy/branch/cpython-extension/pypy/rlib/test/test_rmarshal.py pypy/branch/cpython-extension/pypy/rlib/test/test_rsocket.py pypy/branch/cpython-extension/pypy/rlib/test/test_rstruct.py pypy/branch/cpython-extension/pypy/rpython/exceptiondata.py pypy/branch/cpython-extension/pypy/rpython/llinterp.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/llgroup.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/lltype.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/opimpl.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_ll2ctypes.py pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_llgroup.py pypy/branch/cpython-extension/pypy/rpython/memory/gc/generation.py pypy/branch/cpython-extension/pypy/rpython/memory/gc/hybrid.py pypy/branch/cpython-extension/pypy/rpython/memory/gc/test/test_direct.py pypy/branch/cpython-extension/pypy/rpython/memory/test/test_gc.py pypy/branch/cpython-extension/pypy/rpython/memory/test/test_transformed_gc.py pypy/branch/cpython-extension/pypy/rpython/test/test_rbuiltin.py pypy/branch/cpython-extension/pypy/rpython/test/test_rdict.py pypy/branch/cpython-extension/pypy/rpython/test/test_rint.py pypy/branch/cpython-extension/pypy/rpython/tool/rffi_platform.py pypy/branch/cpython-extension/pypy/rpython/tool/rfficache.py pypy/branch/cpython-extension/pypy/rpython/tool/test/test_rffi_platform.py pypy/branch/cpython-extension/pypy/tool/terminal.py pypy/branch/cpython-extension/pypy/translator/c/gcc/test/conftest.py pypy/branch/cpython-extension/pypy/translator/c/genc.py pypy/branch/cpython-extension/pypy/translator/c/node.py pypy/branch/cpython-extension/pypy/translator/c/primitive.py pypy/branch/cpython-extension/pypy/translator/c/src/commondefs.h pypy/branch/cpython-extension/pypy/translator/c/src/exception.h pypy/branch/cpython-extension/pypy/translator/c/src/llgroup.h pypy/branch/cpython-extension/pypy/translator/c/src/main.h pypy/branch/cpython-extension/pypy/translator/c/test/test_exception.py pypy/branch/cpython-extension/pypy/translator/c/test/test_lltyped.py pypy/branch/cpython-extension/pypy/translator/c/test/test_newgc.py pypy/branch/cpython-extension/pypy/translator/c/test/test_refcount.py (props changed) pypy/branch/cpython-extension/pypy/translator/c/test/test_standalone.py pypy/branch/cpython-extension/pypy/translator/c/test/test_typed.py pypy/branch/cpython-extension/pypy/translator/exceptiontransform.py pypy/branch/cpython-extension/pypy/translator/goal/translate.py pypy/branch/cpython-extension/pypy/translator/jvm/test/test_backendopt.py pypy/branch/cpython-extension/pypy/translator/jvm/test/test_rarithmetic.py pypy/branch/cpython-extension/pypy/translator/platform/__init__.py pypy/branch/cpython-extension/pypy/translator/platform/linux.py pypy/branch/cpython-extension/pypy/translator/platform/maemo.py pypy/branch/cpython-extension/pypy/translator/platform/posix.py pypy/branch/cpython-extension/pypy/translator/platform/test/test_maemo.py pypy/branch/cpython-extension/pypy/translator/platform/test/test_makefile.py pypy/branch/cpython-extension/pypy/translator/stackless/code.py Log: merge from trunk Modified: pypy/branch/cpython-extension/lib-python/conftest.py ============================================================================== --- pypy/branch/cpython-extension/lib-python/conftest.py (original) +++ pypy/branch/cpython-extension/lib-python/conftest.py Wed Mar 31 00:17:06 2010 @@ -282,7 +282,7 @@ RegrTest('test_largefile.py'), RegrTest('test_linuxaudiodev.py', skip="unsupported extension module"), RegrTest('test_list.py', core=True), - RegrTest('test_locale.py'), + RegrTest('test_locale.py', usemodules="_locale"), RegrTest('test_logging.py', usemodules='thread'), RegrTest('test_long.py', core=True), RegrTest('test_long_future.py', core=True), @@ -479,7 +479,7 @@ RegrTest('test_pep352.py'), RegrTest('test_platform.py'), RegrTest('test_runpy.py'), - RegrTest('test_sqlite.py', usemodules="thread"), + RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), RegrTest('test_startfile.py', skip="bogus test"), RegrTest('test_structmembers.py', skip="depends on _testcapi"), RegrTest('test_urllib2_localnet.py', usemodules="thread"), Modified: pypy/branch/cpython-extension/pypy/doc/coding-guide.txt ============================================================================== --- pypy/branch/cpython-extension/pypy/doc/coding-guide.txt (original) +++ pypy/branch/cpython-extension/pypy/doc/coding-guide.txt Wed Mar 31 00:17:06 2010 @@ -241,11 +241,17 @@ We are using -**integer, float, string, boolean** +**integer, float, boolean** - a lot of, but not all string methods are supported. When slicing a string - it is necessary to prove that the slice start and stop indexes are - non-negative. + works. + +**strings** + + a lot of, but not all string methods are supported. Indexes can be + negative. In case they are not, then you get slightly more efficient + code if the translator can prove that they are non-negative. When + slicing a string it is necessary to prove that the slice start and + stop indexes are non-negative. **tuples** Modified: pypy/branch/cpython-extension/pypy/doc/getting-started-python.txt ============================================================================== --- pypy/branch/cpython-extension/pypy/doc/getting-started-python.txt (original) +++ pypy/branch/cpython-extension/pypy/doc/getting-started-python.txt Wed Mar 31 00:17:06 2010 @@ -42,6 +42,7 @@ * ``python-dev`` * ``python-ctypes`` if you are still using Python2.4 * ``libffi-dev`` + * ``pkg-config`` (to help us locate libffi files) * ``libz-dev`` (for the optional ``zlib`` module) * ``libbz2-dev`` (for the optional ``bz2`` module) * ``libncurses-dev`` (for the optional ``_minimal_curses`` module) Modified: pypy/branch/cpython-extension/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/baseobjspace.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/baseobjspace.py Wed Mar 31 00:17:06 2010 @@ -1,3 +1,5 @@ +import itertools +import pypy from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction from pypy.interpreter.error import OperationError, operationerrfmt @@ -9,11 +11,14 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import make_sure_not_resized from pypy.rlib.timer import DummyTimer, Timer +from pypy.rlib.rarithmetic import r_uint from pypy.rlib import jit import os, sys __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root'] +UINT_MAX_32_BITS = r_uint(4294967295) + class W_Root(object): """This is the abstract root class of all wrapped objects that live @@ -402,7 +407,6 @@ if ('time2' in modules or 'rctime' in modules) and 'time' in modules: modules.remove('time') - import pypy if not self.config.objspace.nofaking: for modname in self.ALL_BUILTIN_MODULES: if not (os.path.exists( @@ -445,19 +449,18 @@ self.builtin_modules['__builtin__'] = self.wrap(w_builtin) self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) - bootstrap_modules = ['sys', 'imp', '__builtin__', 'exceptions'] - installed_builtin_modules = bootstrap_modules[:] + bootstrap_modules = set(('sys', 'imp', '__builtin__', 'exceptions')) + installed_builtin_modules = list(bootstrap_modules) - self.export_builtin_exceptions() + exception_types_w = self.export_builtin_exceptions() # initialize with "bootstrap types" from objspace (e.g. w_None) - for name, value in self.__dict__.items(): - if name.startswith('w_') and not name.endswith('Type'): - name = name[2:] - #print "setitem: space instance %-20s into builtins" % name - self.setitem(self.builtin.w_dict, self.wrap(name), value) + types_w = itertools.chain(self.get_builtin_types().iteritems(), + exception_types_w.iteritems()) + for name, w_type in types_w: + self.setitem(self.builtin.w_dict, self.wrap(name), w_type) - # install mixed and faked modules and set builtin_module_names on sys + # install mixed and faked modules for mixedname in self.get_builtinmodule_to_install(): if (mixedname not in bootstrap_modules and not mixedname.startswith('faked+')): @@ -475,17 +478,28 @@ self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'), w_builtin_module_names) + def get_builtin_types(self): + """Get a dictionary mapping the names of builtin types to the type + objects.""" + raise NotImplementedError + def export_builtin_exceptions(self): """NOT_RPYTHON""" w_dic = self.exceptions_module.getdict() - names_w = self.unpackiterable(self.call_function(self.getattr(w_dic, self.wrap("keys")))) - - for w_name in names_w: + w_keys = self.call_method(w_dic, "keys") + exc_types_w = {} + for w_name in self.unpackiterable(w_keys): name = self.str_w(w_name) if not name.startswith('__'): excname = name w_exc = self.getitem(w_dic, w_name) - setattr(self, "w_"+excname, w_exc) + exc_types_w[name] = w_exc + setattr(self, "w_" + excname, w_exc) + # Make a prebuilt recursion error + w_msg = self.wrap("maximum recursion depth exceeded") + self.prebuilt_recursion_error = OperationError(self.w_RuntimeError, + w_msg) + return exc_types_w def install_mixedmodule(self, mixedname, installed_builtin_modules): """NOT_RPYTHON""" @@ -1095,6 +1109,37 @@ self.wrap("expected a non-negative integer")) return value + def c_int_w(self, w_obj): + # Like space.int_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.int_w(w_obj) + if value < -2147483647-1 or value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit integer")) + return value + + def c_uint_w(self, w_obj): + # Like space.uint_w(), but raises an app-level OverflowError if + # the integer does not fit in 32 bits. Mostly here for gateway.py. + value = self.uint_w(w_obj) + if value > UINT_MAX_32_BITS: + raise OperationError(self.w_OverflowError, + self.wrap("expected an unsigned 32-bit integer")) + return value + + def c_nonnegint_w(self, w_obj): + # Like space.int_w(), but raises an app-level ValueError if + # the integer is negative or does not fit in 32 bits. 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")) + if value > 2147483647: + raise OperationError(self.w_OverflowError, + self.wrap("expected a 32-bit integer")) + return value + def warn(self, msg, w_warningcls): self.appexec([self.wrap(msg), w_warningcls], """(msg, warningcls): import warnings Modified: pypy/branch/cpython-extension/pypy/interpreter/error.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/error.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/error.py Wed Mar 31 00:17:06 2010 @@ -344,7 +344,7 @@ else: _WINDOWS = True - def wrap_windowserror(space, e): + def wrap_windowserror(space, e, filename=None): from pypy.rlib import rwin32 winerror = e.winerror @@ -353,16 +353,19 @@ except ValueError: msg = 'Windows Error %d' % winerror exc = space.w_WindowsError - w_error = space.call_function(exc, - space.wrap(winerror), - space.wrap(msg)) + if filename is not None: + w_error = space.call_function(exc, space.wrap(winerror), + space.wrap(msg), space.wrap(filename)) + else: + w_error = space.call_function(exc, space.wrap(winerror), + space.wrap(msg)) return OperationError(exc, w_error) -def wrap_oserror(space, e, exception_name='w_OSError'): - assert isinstance(e, OSError) +def wrap_oserror(space, e, filename=None, exception_name='w_OSError'): + assert isinstance(e, OSError) if _WINDOWS and isinstance(e, WindowsError): - return wrap_windowserror(space, e) + return wrap_windowserror(space, e, filename) errno = e.errno try: @@ -370,8 +373,10 @@ except ValueError: msg = 'error %d' % errno exc = getattr(space, exception_name) - w_error = space.call_function(exc, - space.wrap(errno), - space.wrap(msg)) + if filename is not None: + w_error = space.call_function(exc, space.wrap(errno), + space.wrap(msg), space.wrap(filename)) + else: + w_error = space.call_function(exc, space.wrap(errno), space.wrap(msg)) return OperationError(exc, w_error) -wrap_oserror._annspecialcase_ = 'specialize:arg(2)' +wrap_oserror._annspecialcase_ = 'specialize:arg(3)' Modified: pypy/branch/cpython-extension/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/executioncontext.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/executioncontext.py Wed Mar 31 00:17:06 2010 @@ -478,12 +478,17 @@ def __init__(self, space): AsyncAction.__init__(self, space) self.dying_objects_w = [] + self.weakrefs_w = [] self.finalizers_lock_count = 0 def register_dying_object(self, w_obj): self.dying_objects_w.append(w_obj) self.fire() + def register_weakref_callback(self, w_ref): + self.weakrefs_w.append(w_ref) + self.fire() + def perform(self, executioncontext, frame): if self.finalizers_lock_count > 0: return @@ -505,8 +510,12 @@ # finally, this calls the interp-level destructor for the # cases where there is both an app-level and a built-in __del__. w_obj._call_builtin_destructor() - - + pending_w = self.weakrefs_w + self.weakrefs_w = [] + for i in range(len(pending_w)): + w_ref = pending_w[i] + w_ref.activate_callback() + class FrameTraceAction(AsyncAction): """An action that calls the local trace functions (w_f_trace).""" Modified: pypy/branch/cpython-extension/pypy/interpreter/gateway.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/gateway.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/gateway.py Wed Mar 31 00:17:06 2010 @@ -22,6 +22,8 @@ from pypy.interpreter.argument import Arguments, Signature from pypy.tool.sourcetools import NiceCompile, compile2 from pypy.rlib.rarithmetic import r_longlong, r_int, r_ulonglong, r_uint +from pypy.rlib import rstackovf +from pypy.rlib.objectmodel import we_are_translated # internal non-translatable parts: import py @@ -126,6 +128,15 @@ def visit_nonnegint(self, el, app_sig): self.checked_space_method(el, app_sig) + def visit_c_int(self, el, app_sig): + self.checked_space_method(el, app_sig) + + def visit_c_uint(self, el, app_sig): + self.checked_space_method(el, app_sig) + + def visit_c_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() @@ -230,6 +241,15 @@ def visit_nonnegint(self, typ): self.run_args.append("space.nonnegint_w(%s)" % (self.scopenext(),)) + def visit_c_int(self, typ): + self.run_args.append("space.c_int_w(%s)" % (self.scopenext(),)) + + def visit_c_uint(self, typ): + self.run_args.append("space.c_uint_w(%s)" % (self.scopenext(),)) + + def visit_c_nonnegint(self, typ): + self.run_args.append("space.c_nonnegint_w(%s)" % (self.scopenext(),)) + def _make_unwrap_activation_class(self, unwrap_spec, cache={}): try: key = tuple(unwrap_spec) @@ -348,6 +368,15 @@ def visit_nonnegint(self, typ): self.unwrap.append("space.nonnegint_w(%s)" % (self.nextarg(),)) + def visit_c_int(self, typ): + self.unwrap.append("space.c_int_w(%s)" % (self.nextarg(),)) + + def visit_c_uint(self, typ): + self.unwrap.append("space.c_uint_w(%s)" % (self.nextarg(),)) + + def visit_c_nonnegint(self, typ): + self.unwrap.append("space.c_nonnegint_w(%s)" % (self.nextarg(),)) + def make_fastfunc(unwrap_spec, func): unwrap_info = UnwrapSpec_FastFunc_Unwrap() unwrap_info.apply_over(unwrap_spec) @@ -521,27 +550,33 @@ func.defs_w, self.minargs) try: w_result = activation._run(space, scope_w) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, - space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: if w_obj is not None: args = args.prepend(w_obj) return scope_w[0].descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result + def handle_exception(self, space, e): + try: + if not we_are_translated(): + raise + raise e + except KeyboardInterrupt: + raise OperationError(space.w_KeyboardInterrupt, + space.w_None) + except MemoryError: + raise OperationError(space.w_MemoryError, space.w_None) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow() + raise space.prebuilt_recursion_error + # (verbose) performance hack below class BuiltinCodePassThroughArguments0(BuiltinCode): @@ -551,20 +586,13 @@ space = func.space try: w_result = self.func__args__(space, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -577,20 +605,13 @@ space = func.space try: w_result = self.func__args__(space, w_obj, args) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return args.firstarg().descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, args.prepend(w_obj)) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -602,15 +623,11 @@ def fastcall_0(self, space, w_func): try: w_result = self.fastfunc_0(space) - except KeyboardInterrupt: - 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))) + except DescrMismatch: + raise OperationError(space.w_SystemError, + space.wrap("unexpected DescrMismatch error")) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -622,20 +639,13 @@ def fastcall_1(self, space, w_func, w1): try: w_result = self.fastfunc_1(space, w1) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -647,20 +657,13 @@ def fastcall_2(self, space, w_func, w1, w2): try: w_result = self.fastfunc_2(space, w1, w2) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -672,20 +675,13 @@ def fastcall_3(self, space, func, w1, w2, w3): try: w_result = self.fastfunc_3(space, w1, w2, w3) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result @@ -697,21 +693,14 @@ def fastcall_4(self, space, func, w1, w2, w3, w4): try: w_result = self.fastfunc_4(space, w1, w2, w3, w4) - except KeyboardInterrupt: - raise OperationError(space.w_KeyboardInterrupt, space.w_None) - except MemoryError: - raise OperationError(space.w_MemoryError, space.w_None) - except NotImplementedError, e: - raise - except RuntimeError, e: - raise OperationError(space.w_RuntimeError, - space.wrap("internal error: " + str(e))) - except DescrMismatch, e: + except DescrMismatch: return w1.descr_call_mismatch(space, self.descrmismatch_op, self.descr_reqcls, Arguments(space, [w1, w2, w3, w4])) + except Exception, e: + raise self.handle_exception(space, e) if w_result is None: w_result = space.w_None return w_result Modified: pypy/branch/cpython-extension/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/nestedscope.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/nestedscope.py Wed Mar 31 00:17:06 2010 @@ -169,51 +169,51 @@ ### extra opcodes ### - def LOAD_CLOSURE(f, varindex, *ignored): + def LOAD_CLOSURE(self, varindex, next_instr): # nested scopes: access the cell object - cell = f.cells[varindex] - w_value = f.space.wrap(cell) - f.pushvalue(w_value) + cell = self.cells[varindex] + w_value = self.space.wrap(cell) + self.pushvalue(w_value) - def LOAD_DEREF(f, varindex, *ignored): + def LOAD_DEREF(self, varindex, next_instr): # nested scopes: access a variable through its cell object - cell = f.cells[varindex] + cell = self.cells[varindex] try: w_value = cell.get() except ValueError: - varname = f.getfreevarname(varindex) - if f.iscellvar(varindex): + varname = self.getfreevarname(varindex) + if self.iscellvar(varindex): message = "local variable '%s' referenced before assignment"%varname - w_exc_type = f.space.w_UnboundLocalError + w_exc_type = self.space.w_UnboundLocalError else: message = ("free variable '%s' referenced before assignment" " in enclosing scope"%varname) - w_exc_type = f.space.w_NameError - raise OperationError(w_exc_type, f.space.wrap(message)) + w_exc_type = self.space.w_NameError + raise OperationError(w_exc_type, self.space.wrap(message)) else: - f.pushvalue(w_value) + self.pushvalue(w_value) - def STORE_DEREF(f, varindex, *ignored): + def STORE_DEREF(self, varindex, next_instr): # nested scopes: access a variable through its cell object - w_newvalue = f.popvalue() - cell = f.cells[varindex] + w_newvalue = self.popvalue() + cell = self.cells[varindex] cell.set(w_newvalue) @jit.unroll_safe - def MAKE_CLOSURE(f, numdefaults, *ignored): - w_codeobj = f.popvalue() - codeobj = f.space.interp_w(pycode.PyCode, w_codeobj) + def MAKE_CLOSURE(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + codeobj = self.space.interp_w(pycode.PyCode, w_codeobj) if codeobj.magic >= 0xa0df281: # CPython 2.5 AST branch merge - w_freevarstuple = f.popvalue() - freevars = [f.space.interp_w(Cell, cell) - for cell in f.space.fixedview(w_freevarstuple)] + w_freevarstuple = self.popvalue() + freevars = [self.space.interp_w(Cell, cell) + for cell in self.space.fixedview(w_freevarstuple)] else: nfreevars = len(codeobj.co_freevars) - freevars = [f.space.interp_w(Cell, f.popvalue()) + freevars = [self.space.interp_w(Cell, self.popvalue()) for i in range(nfreevars)] freevars.reverse() - defaultarguments = [f.popvalue() for i in range(numdefaults)] + defaultarguments = [self.popvalue() for i in range(numdefaults)] defaultarguments.reverse() - fn = function.Function(f.space, codeobj, f.w_globals, + fn = function.Function(self.space, codeobj, self.w_globals, defaultarguments, freevars) - f.pushvalue(f.space.wrap(fn)) + self.pushvalue(self.space.wrap(fn)) Modified: pypy/branch/cpython-extension/pypy/interpreter/pyframe.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/pyframe.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/pyframe.py Wed Mar 31 00:17:06 2010 @@ -64,6 +64,8 @@ self.fastlocals_w = [None]*self.numlocals make_sure_not_resized(self.fastlocals_w) self.f_lineno = code.co_firstlineno + # Keep from having to call space.wrap in a RuntimeError + self._recursion_error = space.wrap("maximum recursion depth exceeded") def append_block(self, block): block.previous = self.lastblock Modified: pypy/branch/cpython-extension/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/pyopcode.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/pyopcode.py Wed Mar 31 00:17:06 2010 @@ -18,26 +18,27 @@ from pypy.tool.stdlib_opcode import unrolling_opcode_descs from pypy.tool.stdlib_opcode import opcode_method_names from pypy.rlib.unroll import unrolling_iterable +from pypy.rlib import rstackovf def unaryoperation(operationname): """NOT_RPYTHON""" - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_1 = f.popvalue() + def opimpl(self, *ignored): + operation = getattr(self.space, operationname) + w_1 = self.popvalue() w_result = operation(w_1) - f.pushvalue(w_result) + self.pushvalue(w_result) opimpl.unaryop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) def binaryoperation(operationname): - """NOT_RPYTHON""" - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_2 = f.popvalue() - w_1 = f.popvalue() + """NOT_RPYTHON""" + def opimpl(self, *ignored): + operation = getattr(self.space, operationname) + w_2 = self.popvalue() + w_1 = self.popvalue() w_result = operation(w_1, w_2) - f.pushvalue(w_result) + self.pushvalue(w_result) opimpl.binop = operationname return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) @@ -63,10 +64,10 @@ class __extend__(pyframe.PyFrame): """A PyFrame that knows about interpretation of standard Python opcodes minus the ones related to nested scopes.""" - + # for logbytecode: last_opcode = -1 - + ### opcode dispatch ### def dispatch(self, pycode, next_instr, ec): @@ -106,20 +107,12 @@ 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 - # in translated PyPy - msg = "internal error (stack overflow?)" - else: - msg = str(e) - next_instr = self.handle_asynchronous_error(ec, - self.space.w_RuntimeError, - self.space.wrap(msg)) + except rstackovf.StackOverflow, e: + rstackovf.check_stack_overflow() + w_err = self.space.prebuilt_recursion_error + next_instr = self.handle_operation_error(ec, w_err) return next_instr - + def handle_asynchronous_error(self, ec, w_type, w_value=None): # catch asynchronous exceptions and turn them # into OperationErrors @@ -235,7 +228,7 @@ return next_instr if opcode == opcodedesc.JUMP_ABSOLUTE.index: - return self.JUMP_ABSOLUTE(oparg, next_instr, ec) + return self.jump_absolute(oparg, next_instr, ec) if we_are_translated(): from pypy.rlib import rstack # for resume points @@ -245,7 +238,7 @@ if not opdesc.is_enabled(space): continue if not hasattr(pyframe.PyFrame, opdesc.methodname): - continue # e.g. for JUMP_FORWARD, implemented above + continue # e.g. for JUMP_ABSOLUTE, implemented above if opcode == opdesc.index: # dispatch to the opcode method @@ -307,78 +300,66 @@ ## See also nestedscope.py for the rest. ## - # the 'self' argument of opcode implementations is called 'f' - # for historical reasons - - def NOP(f, *ignored): + def NOP(self, oparg, next_instr): pass - def LOAD_FAST(f, varindex, *ignored): + def LOAD_FAST(self, varindex, next_instr): # access a local variable directly - w_value = f.fastlocals_w[varindex] + w_value = self.fastlocals_w[varindex] if w_value is None: - f._load_fast_failed(varindex) - f.pushvalue(w_value) + self._load_fast_failed(varindex) + self.pushvalue(w_value) LOAD_FAST._always_inline_ = True - def _load_fast_failed(f, varindex): - varname = f.getlocalvarname(varindex) + def _load_fast_failed(self, varindex): + varname = self.getlocalvarname(varindex) message = "local variable '%s' referenced before assignment" - raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) + raise operationerrfmt(self.space.w_UnboundLocalError, message, varname) _load_fast_failed._dont_inline_ = True - def LOAD_CONST(f, constindex, *ignored): - w_const = f.getconstant_w(constindex) - f.pushvalue(w_const) + def LOAD_CONST(self, constindex, next_instr): + w_const = self.getconstant_w(constindex) + self.pushvalue(w_const) - def STORE_FAST(f, varindex, *ignored): - w_newvalue = f.popvalue() + def STORE_FAST(self, varindex, next_instr): + w_newvalue = self.popvalue() assert w_newvalue is not None - f.fastlocals_w[varindex] = w_newvalue - #except: - # print "exception: got index error" - # print " varindex:", varindex - # print " len(locals_w)", len(f.locals_w) - # import dis - # print dis.dis(f.pycode) - # print "co_varnames", f.pycode.co_varnames - # print "co_nlocals", f.pycode.co_nlocals - # raise - - def POP_TOP(f, *ignored): - f.popvalue() - - def ROT_TWO(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_2) - - def ROT_THREE(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - w_3 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_3) - f.pushvalue(w_2) - - def ROT_FOUR(f, *ignored): - w_1 = f.popvalue() - w_2 = f.popvalue() - w_3 = f.popvalue() - w_4 = f.popvalue() - f.pushvalue(w_1) - f.pushvalue(w_4) - f.pushvalue(w_3) - f.pushvalue(w_2) - - def DUP_TOP(f, *ignored): - w_1 = f.peekvalue() - f.pushvalue(w_1) + self.fastlocals_w[varindex] = w_newvalue + + def POP_TOP(self, oparg, next_instr): + self.popvalue() + + def ROT_TWO(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_2) + + def ROT_THREE(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def ROT_FOUR(self, oparg, next_instr): + w_1 = self.popvalue() + w_2 = self.popvalue() + w_3 = self.popvalue() + w_4 = self.popvalue() + self.pushvalue(w_1) + self.pushvalue(w_4) + self.pushvalue(w_3) + self.pushvalue(w_2) + + def DUP_TOP(self, oparg, next_instr): + w_1 = self.peekvalue() + self.pushvalue(w_1) - def DUP_TOPX(f, itemcount, *ignored): + def DUP_TOPX(self, itemcount, next_instr): assert 1 <= itemcount <= 5, "limitation of the current interpreter" - f.dupvalues(itemcount) + self.dupvalues(itemcount) UNARY_POSITIVE = unaryoperation("pos") UNARY_NEGATIVE = unaryoperation("neg") @@ -386,11 +367,11 @@ UNARY_CONVERT = unaryoperation("repr") UNARY_INVERT = unaryoperation("invert") - def BINARY_POWER(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = f.space.pow(w_1, w_2, f.space.w_None) - f.pushvalue(w_result) + def BINARY_POWER(self, oparg, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = self.space.pow(w_1, w_2, self.space.w_None) + self.pushvalue(w_result) BINARY_MULTIPLY = binaryoperation("mul") BINARY_TRUE_DIVIDE = binaryoperation("truediv") @@ -407,11 +388,11 @@ BINARY_XOR = binaryoperation("xor") BINARY_OR = binaryoperation("or_") - def INPLACE_POWER(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = f.space.inplace_pow(w_1, w_2) - f.pushvalue(w_result) + def INPLACE_POWER(self, oparg, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() + w_result = self.space.inplace_pow(w_1, w_2) + self.pushvalue(w_result) INPLACE_MULTIPLY = binaryoperation("inplace_mul") INPLACE_TRUE_DIVIDE = binaryoperation("inplace_truediv") @@ -427,129 +408,130 @@ INPLACE_XOR = binaryoperation("inplace_xor") INPLACE_OR = binaryoperation("inplace_or") - def slice(f, w_start, w_end): - w_obj = f.popvalue() - w_result = f.space.getslice(w_obj, w_start, w_end) - f.pushvalue(w_result) - - def SLICE_0(f, *ignored): - f.slice(f.space.w_None, f.space.w_None) - - def SLICE_1(f, *ignored): - w_start = f.popvalue() - f.slice(w_start, f.space.w_None) - - def SLICE_2(f, *ignored): - w_end = f.popvalue() - f.slice(f.space.w_None, w_end) - - def SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.slice(w_start, w_end) - - def storeslice(f, w_start, w_end): - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setslice(w_obj, w_start, w_end, w_newvalue) - - def STORE_SLICE_0(f, *ignored): - f.storeslice(f.space.w_None, f.space.w_None) - - def STORE_SLICE_1(f, *ignored): - w_start = f.popvalue() - f.storeslice(w_start, f.space.w_None) - - def STORE_SLICE_2(f, *ignored): - w_end = f.popvalue() - f.storeslice(f.space.w_None, w_end) - - def STORE_SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.storeslice(w_start, w_end) - - def deleteslice(f, w_start, w_end): - w_obj = f.popvalue() - f.space.delslice(w_obj, w_start, w_end) - - def DELETE_SLICE_0(f, *ignored): - f.deleteslice(f.space.w_None, f.space.w_None) - - def DELETE_SLICE_1(f, *ignored): - w_start = f.popvalue() - f.deleteslice(w_start, f.space.w_None) - - def DELETE_SLICE_2(f, *ignored): - w_end = f.popvalue() - f.deleteslice(f.space.w_None, w_end) - - def DELETE_SLICE_3(f, *ignored): - w_end = f.popvalue() - w_start = f.popvalue() - f.deleteslice(w_start, w_end) + def slice(self, w_start, w_end): + w_obj = self.popvalue() + w_result = self.space.getslice(w_obj, w_start, w_end) + self.pushvalue(w_result) + + def SLICE_0(self, oparg, next_instr): + self.slice(self.space.w_None, self.space.w_None) + + def SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.slice(w_start, self.space.w_None) + + def SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.slice(self.space.w_None, w_end) + + def SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.slice(w_start, w_end) + + def storeslice(self, w_start, w_end): + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setslice(w_obj, w_start, w_end, w_newvalue) + + def STORE_SLICE_0(self, oparg, next_instr): + self.storeslice(self.space.w_None, self.space.w_None) + + def STORE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.storeslice(w_start, self.space.w_None) + + def STORE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.storeslice(self.space.w_None, w_end) + + def STORE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.storeslice(w_start, w_end) + + def deleteslice(self, w_start, w_end): + w_obj = self.popvalue() + self.space.delslice(w_obj, w_start, w_end) + + def DELETE_SLICE_0(self, oparg, next_instr): + self.deleteslice(self.space.w_None, self.space.w_None) + + def DELETE_SLICE_1(self, oparg, next_instr): + w_start = self.popvalue() + self.deleteslice(w_start, self.space.w_None) + + def DELETE_SLICE_2(self, oparg, next_instr): + w_end = self.popvalue() + self.deleteslice(self.space.w_None, w_end) + + def DELETE_SLICE_3(self, oparg, next_instr): + w_end = self.popvalue() + w_start = self.popvalue() + self.deleteslice(w_start, w_end) - def STORE_SUBSCR(f, *ignored): + def STORE_SUBSCR(self, oparg, next_instr): "obj[subscr] = newvalue" - w_subscr = f.popvalue() - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setitem(w_obj, w_subscr, w_newvalue) + w_subscr = self.popvalue() + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setitem(w_obj, w_subscr, w_newvalue) - def DELETE_SUBSCR(f, *ignored): + def DELETE_SUBSCR(self, oparg, next_instr): "del obj[subscr]" - w_subscr = f.popvalue() - w_obj = f.popvalue() - f.space.delitem(w_obj, w_subscr) - - def PRINT_EXPR(f, *ignored): - w_expr = f.popvalue() - print_expr(f.space, w_expr) - - def PRINT_ITEM_TO(f, *ignored): - w_stream = f.popvalue() - w_item = f.popvalue() - if f.space.is_w(w_stream, f.space.w_None): - w_stream = sys_stdout(f.space) # grumble grumble special cases - print_item_to(f.space, w_item, w_stream) - - def PRINT_ITEM(f, *ignored): - w_item = f.popvalue() - print_item(f.space, w_item) - - def PRINT_NEWLINE_TO(f, *ignored): - w_stream = f.popvalue() - if f.space.is_w(w_stream, f.space.w_None): - w_stream = sys_stdout(f.space) # grumble grumble special cases - print_newline_to(f.space, w_stream) + w_subscr = self.popvalue() + w_obj = self.popvalue() + self.space.delitem(w_obj, w_subscr) + + def PRINT_EXPR(self, oparg, next_instr): + w_expr = self.popvalue() + print_expr(self.space, w_expr) + + def PRINT_ITEM_TO(self, oparg, next_instr): + w_stream = self.popvalue() + w_item = self.popvalue() + if self.space.is_w(w_stream, self.space.w_None): + w_stream = sys_stdout(self.space) # grumble grumble special cases + print_item_to(self.space, w_item, w_stream) + + def PRINT_ITEM(self, oparg, next_instr): + w_item = self.popvalue() + print_item(self.space, w_item) + + def PRINT_NEWLINE_TO(self, oparg, next_instr): + w_stream = self.popvalue() + if self.space.is_w(w_stream, self.space.w_None): + w_stream = sys_stdout(self.space) # grumble grumble special cases + print_newline_to(self.space, w_stream) - def PRINT_NEWLINE(f, *ignored): - print_newline(f.space) + def PRINT_NEWLINE(self, oparg, next_instr): + print_newline(self.space) - def BREAK_LOOP(f, *ignored): - next_instr = f.unrollstack_and_jump(SBreakLoop.singleton) - return next_instr + def BREAK_LOOP(self, oparg, next_instr): + return self.unrollstack_and_jump(SBreakLoop.singleton) - def CONTINUE_LOOP(f, startofloop, *ignored): + def CONTINUE_LOOP(self, startofloop, next_instr): unroller = SContinueLoop(startofloop) - next_instr = f.unrollstack_and_jump(unroller) - return next_instr + return self.unrollstack_and_jump(unroller) - def RAISE_VARARGS(f, nbargs, *ignored): - space = f.space + def RAISE_VARARGS(self, nbargs, next_instr): + space = self.space if nbargs == 0: operror = space.getexecutioncontext().sys_exc_info() if operror is None: raise OperationError(space.w_TypeError, space.wrap("raise: no active exception to re-raise")) # re-raise, no new traceback obj will be attached - f.last_exception = operror + self.last_exception = operror raise Reraise w_value = w_traceback = space.w_None - if nbargs >= 3: w_traceback = f.popvalue() - if nbargs >= 2: w_value = f.popvalue() - if 1: w_type = f.popvalue() + if nbargs >= 3: + w_traceback = self.popvalue() + if nbargs >= 2: + w_value = self.popvalue() + if 1: + w_type = self.popvalue() operror = OperationError(w_type, w_value) operror.normalize_exception(space) if not space.full_exceptions or space.is_w(w_traceback, space.w_None): @@ -563,151 +545,154 @@ # special 3-arguments raise, no new traceback obj will be attached raise RaiseWithExplicitTraceback(operror) - def LOAD_LOCALS(f, *ignored): - f.pushvalue(f.w_locals) + def LOAD_LOCALS(self, oparg, next_instr): + self.pushvalue(self.w_locals) - def EXEC_STMT(f, *ignored): - w_locals = f.popvalue() - w_globals = f.popvalue() - w_prog = f.popvalue() - flags = f.space.getexecutioncontext().compiler.getcodeflags(f.pycode) - w_compile_flags = f.space.wrap(flags) - w_resulttuple = prepare_exec(f.space, f.space.wrap(f), w_prog, + def EXEC_STMT(self, oparg, next_instr): + w_locals = self.popvalue() + w_globals = self.popvalue() + w_prog = self.popvalue() + ec = self.space.getexecutioncontext() + flags = ec.compiler.getcodeflags(self.pycode) + w_compile_flags = self.space.wrap(flags) + w_resulttuple = prepare_exec(self.space, self.space.wrap(self), w_prog, w_globals, w_locals, w_compile_flags, - f.space.wrap(f.get_builtin()), - f.space.gettypeobject(PyCode.typedef)) - w_prog, w_globals, w_locals = f.space.fixedview(w_resulttuple, 3) + self.space.wrap(self.get_builtin()), + self.space.gettypeobject(PyCode.typedef)) + w_prog, w_globals, w_locals = self.space.fixedview(w_resulttuple, 3) - plain = f.w_locals is not None and f.space.is_w(w_locals, f.w_locals) + plain = (self.w_locals is not None and + self.space.is_w(w_locals, self.w_locals)) if plain: - w_locals = f.getdictscope() - co = f.space.interp_w(eval.Code, w_prog) - co.exec_code(f.space, w_globals, w_locals) + w_locals = self.getdictscope() + co = self.space.interp_w(eval.Code, w_prog) + co.exec_code(self.space, w_globals, w_locals) if plain: - f.setdictscope(w_locals) + self.setdictscope(w_locals) - def POP_BLOCK(f, *ignored): - block = f.pop_block() - block.cleanup(f) # the block knows how to clean up the value stack + def POP_BLOCK(self, oparg, next_instr): + block = self.pop_block() + block.cleanup(self) # the block knows how to clean up the value stack - def end_finally(f): + def end_finally(self): # unlike CPython, when we reach this opcode the value stack has # always been set up as follows (topmost first): # [exception type or None] # [exception value or None] # [wrapped stack unroller ] - f.popvalue() # ignore the exception type - f.popvalue() # ignore the exception value - w_unroller = f.popvalue() - unroller = f.space.interpclass_w(w_unroller) + self.popvalue() # ignore the exception type + self.popvalue() # ignore the exception value + w_unroller = self.popvalue() + unroller = self.space.interpclass_w(w_unroller) return unroller - def BUILD_CLASS(f, *ignored): - w_methodsdict = f.popvalue() - w_bases = f.popvalue() - w_name = f.popvalue() - w_metaclass = find_metaclass(f.space, w_bases, - w_methodsdict, f.w_globals, - f.space.wrap(f.get_builtin())) - w_newclass = f.space.call_function(w_metaclass, w_name, - w_bases, w_methodsdict) - f.pushvalue(w_newclass) - - def STORE_NAME(f, varindex, *ignored): - varname = f.getname_u(varindex) - w_newvalue = f.popvalue() - f.space.set_str_keyed_item(f.w_locals, varname, w_newvalue) + def BUILD_CLASS(self, oparg, next_instr): + w_methodsdict = self.popvalue() + w_bases = self.popvalue() + w_name = self.popvalue() + w_metaclass = find_metaclass(self.space, w_bases, + w_methodsdict, self.w_globals, + self.space.wrap(self.get_builtin())) + w_newclass = self.space.call_function(w_metaclass, w_name, + w_bases, w_methodsdict) + self.pushvalue(w_newclass) + + def STORE_NAME(self, varindex, next_instr): + varname = self.getname_u(varindex) + w_newvalue = self.popvalue() + self.space.set_str_keyed_item(self.w_locals, varname, w_newvalue) - def DELETE_NAME(f, varindex, *ignored): - w_varname = f.getname_w(varindex) + def DELETE_NAME(self, varindex, next_instr): + w_varname = self.getname_w(varindex) try: - f.space.delitem(f.w_locals, w_varname) + self.space.delitem(self.w_locals, w_varname) except OperationError, e: # catch KeyErrors and turn them into NameErrors - if not e.match(f.space, f.space.w_KeyError): + if not e.match(self.space, self.space.w_KeyError): raise message = "name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, message, - f.space.str_w(w_varname)) + raise operationerrfmt(self.space.w_NameError, message, + self.space.str_w(w_varname)) - def UNPACK_SEQUENCE(f, itemcount, *ignored): - w_iterable = f.popvalue() + def UNPACK_SEQUENCE(self, itemcount, next_instr): + w_iterable = self.popvalue() try: - items = f.space.fixedview(w_iterable, itemcount) + items = self.space.fixedview(w_iterable, itemcount) except UnpackValueError, e: - raise OperationError(f.space.w_ValueError, f.space.wrap(e.msg)) - f.pushrevvalues(itemcount, items) + w_msg = self.space.wrap(e.msg) + raise OperationError(self.space.w_ValueError, w_msg) + self.pushrevvalues(itemcount, items) - def STORE_ATTR(f, nameindex, *ignored): + def STORE_ATTR(self, nameindex, next_instr): "obj.attributename = newvalue" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - w_newvalue = f.popvalue() - f.space.setattr(w_obj, w_attributename, w_newvalue) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_newvalue = self.popvalue() + self.space.setattr(w_obj, w_attributename, w_newvalue) - def DELETE_ATTR(f, nameindex, *ignored): + def DELETE_ATTR(self, nameindex, next_instr): "del obj.attributename" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - f.space.delattr(w_obj, w_attributename) - - def STORE_GLOBAL(f, nameindex, *ignored): - varname = f.getname_u(nameindex) - w_newvalue = f.popvalue() - f.space.set_str_keyed_item(f.w_globals, varname, w_newvalue) - - def DELETE_GLOBAL(f, nameindex, *ignored): - w_varname = f.getname_w(nameindex) - f.space.delitem(f.w_globals, w_varname) - - def LOAD_NAME(f, nameindex, *ignored): - if f.w_locals is not f.w_globals: - w_varname = f.getname_w(nameindex) - w_value = f.space.finditem(f.w_locals, w_varname) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + self.space.delattr(w_obj, w_attributename) + + def STORE_GLOBAL(self, nameindex, next_instr): + varname = self.getname_u(nameindex) + w_newvalue = self.popvalue() + self.space.set_str_keyed_item(self.w_globals, varname, w_newvalue) + + def DELETE_GLOBAL(self, nameindex, next_instr): + w_varname = self.getname_w(nameindex) + self.space.delitem(self.w_globals, w_varname) + + def LOAD_NAME(self, nameindex, next_instr): + if self.w_locals is not self.w_globals: + w_varname = self.getname_w(nameindex) + w_value = self.space.finditem(self.w_locals, w_varname) if w_value is not None: - f.pushvalue(w_value) + self.pushvalue(w_value) return - f.LOAD_GLOBAL(nameindex) # fall-back + self.LOAD_GLOBAL(nameindex, next_instr) # fall-back - def _load_global(f, varname): - w_value = f.space.finditem_str(f.w_globals, varname) + def _load_global(self, varname): + w_value = self.space.finditem_str(self.w_globals, varname) if w_value is None: # not in the globals, now look in the built-ins - w_value = f.get_builtin().getdictvalue(f.space, varname) + w_value = self.get_builtin().getdictvalue(self.space, varname) if w_value is None: - f._load_global_failed(varname) + self._load_global_failed(varname) return w_value _load_global._always_inline_ = True - def _load_global_failed(f, varname): + def _load_global_failed(self, varname): message = "global name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, message, varname) + raise operationerrfmt(self.space.w_NameError, message, varname) _load_global_failed._dont_inline_ = True - def LOAD_GLOBAL(f, nameindex, *ignored): - f.pushvalue(f._load_global(f.getname_u(nameindex))) + def LOAD_GLOBAL(self, nameindex, next_instr): + self.pushvalue(self._load_global(self.getname_u(nameindex))) LOAD_GLOBAL._always_inline_ = True - def DELETE_FAST(f, varindex, *ignored): - if f.fastlocals_w[varindex] is None: - varname = f.getlocalvarname(varindex) + def DELETE_FAST(self, varindex, next_instr): + if self.fastlocals_w[varindex] is None: + varname = self.getlocalvarname(varindex) message = "local variable '%s' referenced before assignment" - raise operationerrfmt(f.space.w_UnboundLocalError, message, varname) - f.fastlocals_w[varindex] = None - - - def BUILD_TUPLE(f, itemcount, *ignored): - items = f.popvalues(itemcount) - w_tuple = f.space.newtuple(items) - f.pushvalue(w_tuple) - - def BUILD_LIST(f, itemcount, *ignored): - items = f.popvalues_mutable(itemcount) - w_list = f.space.newlist(items) - f.pushvalue(w_list) + raise operationerrfmt(self.space.w_UnboundLocalError, message, + varname) + self.fastlocals_w[varindex] = None + + def BUILD_TUPLE(self, itemcount, next_instr): + items = self.popvalues(itemcount) + w_tuple = self.space.newtuple(items) + self.pushvalue(w_tuple) + + def BUILD_LIST(self, itemcount, next_instr): + items = self.popvalues_mutable(itemcount) + w_list = self.space.newlist(items) + self.pushvalue(w_list) - def BUILD_MAP(f, itemcount, *ignored): + def BUILD_MAP(self, itemcount, next_instr): if not we_are_translated() and sys.version_info >= (2, 6): # We could pre-allocate a dict here # but for the moment this code is not translated. @@ -715,77 +700,92 @@ else: if itemcount != 0: raise BytecodeCorruption - w_dict = f.space.newdict() - f.pushvalue(w_dict) + w_dict = self.space.newdict() + self.pushvalue(w_dict) - def STORE_MAP(f, zero, *ignored): + def STORE_MAP(self, zero, next_instr): if not we_are_translated() and sys.version_info >= (2, 6): - w_key = f.popvalue() - w_value = f.popvalue() - w_dict = f.peekvalue() - f.space.setitem(w_dict, w_key, w_value) + w_key = self.popvalue() + w_value = self.popvalue() + w_dict = self.peekvalue() + self.space.setitem(w_dict, w_key, w_value) else: raise BytecodeCorruption - def LOAD_ATTR(f, nameindex, *ignored): + def LOAD_ATTR(self, nameindex, next_instr): "obj.attributename" - w_attributename = f.getname_w(nameindex) - w_obj = f.popvalue() - w_value = f.space.getattr(w_obj, w_attributename) - f.pushvalue(w_value) + w_attributename = self.getname_w(nameindex) + w_obj = self.popvalue() + w_value = self.space.getattr(w_obj, w_attributename) + self.pushvalue(w_value) LOAD_ATTR._always_inline_ = True - def cmp_lt(f, w_1, w_2): return f.space.lt(w_1, w_2) - def cmp_le(f, w_1, w_2): return f.space.le(w_1, w_2) - def cmp_eq(f, w_1, w_2): return f.space.eq(w_1, w_2) - def cmp_ne(f, w_1, w_2): return f.space.ne(w_1, w_2) - def cmp_gt(f, w_1, w_2): return f.space.gt(w_1, w_2) - def cmp_ge(f, w_1, w_2): return f.space.ge(w_1, w_2) - - def cmp_in(f, w_1, w_2): - return f.space.contains(w_2, w_1) - def cmp_not_in(f, w_1, w_2): - return f.space.not_(f.space.contains(w_2, w_1)) - def cmp_is(f, w_1, w_2): - return f.space.is_(w_1, w_2) - def cmp_is_not(f, w_1, w_2): - return f.space.not_(f.space.is_(w_1, w_2)) - def cmp_exc_match(f, w_1, w_2): - return f.space.newbool(f.space.exception_match(w_1, w_2)) - - def COMPARE_OP(f, testnum, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() + def cmp_lt(self, w_1, w_2): + return self.space.lt(w_1, w_2) + + def cmp_le(self, w_1, w_2): + return self.space.le(w_1, w_2) + + def cmp_eq(self, w_1, w_2): + return self.space.eq(w_1, w_2) + + def cmp_ne(self, w_1, w_2): + return self.space.ne(w_1, w_2) + + def cmp_gt(self, w_1, w_2): + return self.space.gt(w_1, w_2) + + def cmp_ge(self, w_1, w_2): + return self.space.ge(w_1, w_2) + + def cmp_in(self, w_1, w_2): + return self.space.contains(w_2, w_1) + + def cmp_not_in(self, w_1, w_2): + return self.space.not_(self.space.contains(w_2, w_1)) + + def cmp_is(self, w_1, w_2): + return self.space.is_(w_1, w_2) + + def cmp_is_not(self, w_1, w_2): + return self.space.not_(self.space.is_(w_1, w_2)) + + def cmp_exc_match(self, w_1, w_2): + return self.space.newbool(self.space.exception_match(w_1, w_2)) + + def COMPARE_OP(self, testnum, next_instr): + w_2 = self.popvalue() + w_1 = self.popvalue() w_result = None for i, attr in unrolling_compare_dispatch_table: if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) + w_result = getattr(self, attr)(w_1, w_2) break else: raise BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) + self.pushvalue(w_result) - def IMPORT_NAME(f, nameindex, *ignored): - space = f.space - w_modulename = f.getname_w(nameindex) - modulename = f.space.str_w(w_modulename) - w_fromlist = f.popvalue() + def IMPORT_NAME(self, nameindex, next_instr): + space = self.space + w_modulename = self.getname_w(nameindex) + modulename = self.space.str_w(w_modulename) + w_fromlist = self.popvalue() # CPython 2.5 adds an extra argument consumed by this opcode - if f.pycode.magic >= 0xa0df294: - w_flag = f.popvalue() + if self.pycode.magic >= 0xa0df294: + w_flag = self.popvalue() else: w_flag = None - w_import = f.get_builtin().getdictvalue(f.space, '__import__') + w_import = self.get_builtin().getdictvalue(space, '__import__') if w_import is None: raise OperationError(space.w_ImportError, space.wrap("__import__ not found")) - w_locals = f.w_locals + w_locals = self.w_locals if w_locals is None: # CPython does this w_locals = space.w_None w_modulename = space.wrap(modulename) - w_globals = f.w_globals + w_globals = self.w_globals if w_flag is None: w_obj = space.call_function(w_import, w_modulename, w_globals, w_locals, w_fromlist) @@ -793,105 +793,105 @@ w_obj = space.call_function(w_import, w_modulename, w_globals, w_locals, w_fromlist, w_flag) - f.pushvalue(w_obj) + self.pushvalue(w_obj) - def IMPORT_STAR(f, *ignored): - w_module = f.popvalue() - w_locals = f.getdictscope() - import_all_from(f.space, w_module, w_locals) - f.setdictscope(w_locals) - - def IMPORT_FROM(f, nameindex, *ignored): - w_name = f.getname_w(nameindex) - w_module = f.peekvalue() + def IMPORT_STAR(self, oparg, next_instr): + w_module = self.popvalue() + w_locals = self.getdictscope() + import_all_from(self.space, w_module, w_locals) + self.setdictscope(w_locals) + + def IMPORT_FROM(self, nameindex, next_instr): + w_name = self.getname_w(nameindex) + w_module = self.peekvalue() try: - w_obj = f.space.getattr(w_module, w_name) + w_obj = self.space.getattr(w_module, w_name) except OperationError, e: - if not e.match(f.space, f.space.w_AttributeError): + if not e.match(self.space, self.space.w_AttributeError): raise - raise operationerrfmt(f.space.w_ImportError, + raise operationerrfmt(self.space.w_ImportError, "cannot import name '%s'", - f.space.str_w(w_name)) - f.pushvalue(w_obj) + self.space.str_w(w_name)) + self.pushvalue(w_obj) - def JUMP_FORWARD(f, jumpby, next_instr, *ignored): + def jump_absolute(self, jumpto, next_instr, ec): + return jumpto + + def JUMP_FORWARD(self, jumpby, next_instr): next_instr += jumpby return next_instr - def JUMP_IF_FALSE(f, stepby, next_instr, *ignored): - w_cond = f.peekvalue() - if not f.space.is_true(w_cond): + def JUMP_IF_FALSE(self, stepby, next_instr): + w_cond = self.peekvalue() + if not self.space.is_true(w_cond): next_instr += stepby return next_instr - def JUMP_IF_TRUE(f, stepby, next_instr, *ignored): - w_cond = f.peekvalue() - if f.space.is_true(w_cond): + def JUMP_IF_TRUE(self, stepby, next_instr): + w_cond = self.peekvalue() + if self.space.is_true(w_cond): next_instr += stepby return next_instr - def JUMP_ABSOLUTE(f, jumpto, next_instr, *ignored): - return jumpto + def GET_ITER(self, oparg, next_instr): + w_iterable = self.popvalue() + w_iterator = self.space.iter(w_iterable) + self.pushvalue(w_iterator) - def GET_ITER(f, *ignored): - w_iterable = f.popvalue() - w_iterator = f.space.iter(w_iterable) - f.pushvalue(w_iterator) - - def FOR_ITER(f, jumpby, next_instr, *ignored): - w_iterator = f.peekvalue() + def FOR_ITER(self, jumpby, next_instr): + w_iterator = self.peekvalue() try: - w_nextitem = f.space.next(w_iterator) + w_nextitem = self.space.next(w_iterator) except OperationError, e: - if not e.match(f.space, f.space.w_StopIteration): - raise + if not e.match(self.space, self.space.w_StopIteration): + raise # iterator exhausted - f.popvalue() + self.popvalue() next_instr += jumpby else: - f.pushvalue(w_nextitem) + self.pushvalue(w_nextitem) return next_instr - def FOR_LOOP(f, oparg, *ignored): + def FOR_LOOP(self, oparg, next_instr): raise BytecodeCorruption, "old opcode, no longer in use" - def SETUP_LOOP(f, offsettoend, next_instr, *ignored): - block = LoopBlock(f, next_instr + offsettoend) - f.append_block(block) - - def SETUP_EXCEPT(f, offsettoend, next_instr, *ignored): - block = ExceptBlock(f, next_instr + offsettoend) - f.append_block(block) - - def SETUP_FINALLY(f, offsettoend, next_instr, *ignored): - block = FinallyBlock(f, next_instr + offsettoend) - f.append_block(block) + def SETUP_LOOP(self, offsettoend, next_instr): + block = LoopBlock(self, next_instr + offsettoend) + self.append_block(block) + + def SETUP_EXCEPT(self, offsettoend, next_instr): + block = ExceptBlock(self, next_instr + offsettoend) + self.append_block(block) + + def SETUP_FINALLY(self, offsettoend, next_instr): + block = FinallyBlock(self, next_instr + offsettoend) + self.append_block(block) - def WITH_CLEANUP(f, *ignored): + def WITH_CLEANUP(self, oparg, next_instr): # see comment in END_FINALLY for stack state - w_exitfunc = f.popvalue() - w_unroller = f.peekvalue(2) - unroller = f.space.interpclass_w(w_unroller) + w_exitfunc = self.popvalue() + w_unroller = self.peekvalue(2) + unroller = self.space.interpclass_w(w_unroller) if isinstance(unroller, SApplicationException): operr = unroller.operr - w_result = f.space.call_function(w_exitfunc, - operr.w_type, - operr.get_w_value(f.space), - operr.application_traceback) - if f.space.is_true(w_result): + w_result = self.space.call_function(w_exitfunc, + operr.w_type, + operr.get_w_value(self.space), + operr.application_traceback) + if self.space.is_true(w_result): # __exit__() returned True -> Swallow the exception. - f.settopvalue(f.space.w_None, 2) + self.settopvalue(self.space.w_None, 2) else: - f.space.call_function(w_exitfunc, - f.space.w_None, - f.space.w_None, - f.space.w_None) - + self.space.call_function(w_exitfunc, + self.space.w_None, + self.space.w_None, + self.space.w_None) + @jit.unroll_safe - def call_function(f, oparg, w_star=None, w_starstar=None): + def call_function(self, 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 if n_keywords: @@ -901,126 +901,121 @@ n_keywords -= 1 if n_keywords < 0: break - w_value = f.popvalue() - w_key = f.popvalue() - key = f.space.str_w(w_key) + w_value = self.popvalue() + w_key = self.popvalue() + key = self.space.str_w(w_key) keywords[n_keywords] = key keywords_w[n_keywords] = w_value else: keywords = None keywords_w = None - arguments = f.popvalues(n_arguments) - args = f.argument_factory(arguments, keywords, keywords_w, w_star, w_starstar) - w_function = f.popvalue() - if f.is_being_profiled and is_builtin_code(w_function): - w_result = f.space.call_args_and_c_profile(f, w_function, args) + arguments = self.popvalues(n_arguments) + args = self.argument_factory(arguments, keywords, keywords_w, w_star, + w_starstar) + w_function = self.popvalue() + if self.is_being_profiled and is_builtin_code(w_function): + w_result = self.space.call_args_and_c_profile(self, 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) - - def CALL_FUNCTION(f, oparg, *ignored): + w_result = self.space.call_args(w_function, args) + rstack.resume_point("call_function", self, returns=w_result) + self.pushvalue(w_result) + + def CALL_FUNCTION(self, oparg, next_instr): from pypy.rlib import rstack # for resume points # XXX start of hack for performance if (oparg >> 8) & 0xff == 0: # Only positional arguments nargs = oparg & 0xff - w_function = f.peekvalue(nargs) + w_function = self.peekvalue(nargs) try: - w_result = f.space.call_valuestack(w_function, nargs, f) - rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) + w_result = self.space.call_valuestack(w_function, nargs, self) + rstack.resume_point("CALL_FUNCTION", self, nargs, + returns=w_result) finally: - f.dropvalues(nargs + 1) - f.pushvalue(w_result) + self.dropvalues(nargs + 1) + self.pushvalue(w_result) # XXX end of hack for performance else: # general case - f.call_function(oparg) + self.call_function(oparg) - def CALL_FUNCTION_VAR(f, oparg, *ignored): - w_varargs = f.popvalue() - f.call_function(oparg, w_varargs) - - def CALL_FUNCTION_KW(f, oparg, *ignored): - w_varkw = f.popvalue() - f.call_function(oparg, None, w_varkw) - - def CALL_FUNCTION_VAR_KW(f, oparg, *ignored): - w_varkw = f.popvalue() - w_varargs = f.popvalue() - f.call_function(oparg, w_varargs, w_varkw) - - def MAKE_FUNCTION(f, numdefaults, *ignored): - w_codeobj = f.popvalue() - codeobj = f.space.interp_w(PyCode, w_codeobj) - defaultarguments = f.popvalues(numdefaults) - fn = function.Function(f.space, codeobj, f.w_globals, defaultarguments) - f.pushvalue(f.space.wrap(fn)) + def CALL_FUNCTION_VAR(self, oparg, next_instr): + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs) + + def CALL_FUNCTION_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + self.call_function(oparg, None, w_varkw) + + def CALL_FUNCTION_VAR_KW(self, oparg, next_instr): + w_varkw = self.popvalue() + w_varargs = self.popvalue() + self.call_function(oparg, w_varargs, w_varkw) + + def MAKE_FUNCTION(self, numdefaults, next_instr): + w_codeobj = self.popvalue() + codeobj = self.space.interp_w(PyCode, w_codeobj) + defaultarguments = self.popvalues(numdefaults) + fn = function.Function(self.space, codeobj, self.w_globals, + defaultarguments) + self.pushvalue(self.space.wrap(fn)) - def BUILD_SLICE(f, numargs, *ignored): + def BUILD_SLICE(self, numargs, next_instr): if numargs == 3: - w_step = f.popvalue() + w_step = self.popvalue() elif numargs == 2: - w_step = f.space.w_None + w_step = self.space.w_None else: raise BytecodeCorruption - w_end = f.popvalue() - w_start = f.popvalue() - w_slice = f.space.newslice(w_start, w_end, w_step) - f.pushvalue(w_slice) - - def LIST_APPEND(f, *ignored): - w = f.popvalue() - v = f.popvalue() - f.space.call_method(v, 'append', w) + w_end = self.popvalue() + w_start = self.popvalue() + w_slice = self.space.newslice(w_start, w_end, w_step) + self.pushvalue(w_slice) + + def LIST_APPEND(self, oparg, next_instr): + w = self.popvalue() + v = self.popvalue() + self.space.call_method(v, 'append', w) - def SET_LINENO(f, lineno, *ignored): + def SET_LINENO(self, lineno, next_instr): pass - def CALL_LIKELY_BUILTIN(f, oparg, *ignored): + def CALL_LIKELY_BUILTIN(self, oparg, next_instr): # overridden by faster version in the standard object space. from pypy.module.__builtin__ import OPTIMIZED_BUILTINS varname = OPTIMIZED_BUILTINS[oparg >> 8] - w_function = f._load_global(varname) + w_function = self._load_global(varname) nargs = oparg&0xFF try: - w_result = f.space.call_valuestack(w_function, nargs, f) + w_result = self.space.call_valuestack(w_function, nargs, self) finally: - f.dropvalues(nargs) - f.pushvalue(w_result) + self.dropvalues(nargs) + self.pushvalue(w_result) - def LOOKUP_METHOD(f, nameindex, *ignored): + def LOOKUP_METHOD(self, nameindex, next_instr): # overridden by faster version in the standard object space. - space = f.space - w_obj = f.popvalue() - w_name = f.getname_w(nameindex) + space = self.space + w_obj = self.popvalue() + w_name = self.getname_w(nameindex) w_value = space.getattr(w_obj, w_name) - f.pushvalue(w_value) - #f.pushvalue(None) + self.pushvalue(w_value) - def CALL_METHOD(f, nargs, *ignored): + def CALL_METHOD(self, nargs, next_instr): # overridden by faster version in the standard object space. # 'nargs' is the argument count excluding the implicit 'self' - w_callable = f.peekvalue(nargs) + w_callable = self.peekvalue(nargs) try: - w_result = f.space.call_valuestack(w_callable, nargs, f) + w_result = self.space.call_valuestack(w_callable, nargs, self) finally: - f.dropvalues(nargs + 1) - f.pushvalue(w_result) - -## def EXTENDED_ARG(f, oparg, *ignored): -## opcode = f.nextop() -## oparg = oparg<<16 | f.nextarg() -## fn = f.dispatch_table_w_arg[opcode] -## if fn is None: -## raise BytecodeCorruption -## fn(f, oparg) + self.dropvalues(nargs + 1) + self.pushvalue(w_result) - def MISSING_OPCODE(f, oparg, next_instr, *ignored): + def MISSING_OPCODE(self, oparg, next_instr): ofs = next_instr - 1 - c = f.pycode.co_code[ofs] - name = f.pycode.co_name + c = self.pycode.co_code[ofs] + name = self.pycode.co_name raise BytecodeCorruption("unknown opcode, ofs=%d, code=%d, name=%s" % (ofs, ord(c), name) ) @@ -1259,9 +1254,9 @@ """ applevel implementation of certain system properties, imports and other helpers""" import sys - + def sys_stdout(): - try: + try: return sys.stdout except AttributeError: raise RuntimeError("lost sys.stdout") @@ -1281,7 +1276,7 @@ # add a softspace unless we just printed a string which ends in a '\t' # or '\n' -- or more generally any whitespace character but ' ' if isinstance(x, str) and x and x[-1].isspace() and x[-1]!=' ': - return + return # XXX add unicode handling file_softspace(stream, True) print_item_to._annspecialcase_ = "specialize:argtype(0)" @@ -1330,10 +1325,10 @@ return type(base) elif '__metaclass__' in globals: return globals['__metaclass__'] - else: - try: - return builtin.__metaclass__ - except AttributeError: + else: + try: + return builtin.__metaclass__ + except AttributeError: return type ''', filename=__file__) Modified: pypy/branch/cpython-extension/pypy/interpreter/pyparser/future.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/pyparser/future.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/pyparser/future.py Wed Mar 31 00:17:06 2010 @@ -62,7 +62,7 @@ not recognized as a valid future statement or something that may precede a future statement. """ - + def __init__(self, future_flags, string): self.future_flags = future_flags self.s = string @@ -83,7 +83,7 @@ def start(self): c = self.getc() - if c in ["'", '"'] and not self.docstring_consumed: + if c in ("'", '"', "r", "u") and not self.docstring_consumed: self.consume_docstring() elif c in whitespace_or_newline: self.consume_empty_line() @@ -100,6 +100,10 @@ def consume_docstring(self): self.docstring_consumed = True + if self.getc() == "r": + self.pos += 1 + if self.getc() == "u": + self.pos += 1 endchar = self.getc() if (self.getc() == self.getc(+1) and self.getc() == self.getc(+2)): Modified: pypy/branch/cpython-extension/pypy/interpreter/pyparser/test/test_futureautomaton.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/pyparser/test/test_futureautomaton.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/pyparser/test/test_futureautomaton.py Wed Mar 31 00:17:06 2010 @@ -150,3 +150,20 @@ assert f.flags == fut.CO_FUTURE_ABSOLUTE_IMPORT +def test_raw_doc(): + s = 'r"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT + +def test_unicode_doc(): + s = 'u"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT + +def test_raw_unicode_doc(): + s = 'ru"Doc"\nfrom __future__ import with_statement\n' + f = run(s) + assert f.pos == len(s) + assert f.flags == fut.CO_FUTURE_WITH_STATEMENT Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_executioncontext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_executioncontext.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_executioncontext.py Wed Mar 31 00:17:06 2010 @@ -271,7 +271,11 @@ # would be called import os, sys print sys.executable, self.tmpfile - g = os.popen('"%s" "%s"' % (sys.executable, self.tmpfile), 'r') + if sys.platform == "win32": + cmdformat = '""%s" "%s""' # excellent! tons of "! + else: + cmdformat = "'%s' '%s'" + g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r') data = g.read() g.close() assert 'Called 1' in data Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_gateway.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_gateway.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_gateway.py Wed Mar 31 00:17:06 2010 @@ -197,6 +197,51 @@ space.raises_w(space.w_ValueError, space.call_function, w_app_g, space.wrap(-1)) + def test_interp2app_unwrap_spec_c_int(self): + from pypy.rlib.rarithmetic import r_longlong + space = self.space + w = space.wrap + def g(space, x): + return space.wrap(x + 6) + app_g = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_int']) + app_ug = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_uint']) + app_ng = gateway.interp2app(g, unwrap_spec=[gateway.ObjSpace, + 'c_nonnegint']) + assert app_ug is not app_g + w_app_g = space.wrap(app_g) + w_app_ug = space.wrap(app_ug) + w_app_ng = space.wrap(app_ng) + # + assert self.space.eq_w(space.call_function(w_app_g, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_g, + space.wrap(r_longlong(-0x80000001))) + # + assert self.space.eq_w(space.call_function(w_app_ug, space.wrap(7)), + space.wrap(13)) + assert self.space.eq_w(space.call_function(w_app_ug, + space.wrap(0x7FFFFFFF)), + space.wrap(r_longlong(0x7FFFFFFF+6))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ug, space.wrap(-1)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ug, + space.wrap(r_longlong(0x100000000))) + # + assert self.space.eq_w(space.call_function(w_app_ng, space.wrap(7)), + space.wrap(13)) + space.raises_w(space.w_OverflowError, + space.call_function, w_app_ng, + space.wrap(r_longlong(0x80000000))) + space.raises_w(space.w_ValueError, + space.call_function, w_app_ng, space.wrap(-1)) + def test_interp2app_unwrap_spec_args_w(self): space = self.space w = space.wrap Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_interpreter.py Wed Mar 31 00:17:06 2010 @@ -263,3 +263,12 @@ def test_identity(self): def f(x): return x assert f(666) == 666 + + def test_raise_recursion(self): + def f(): f() + try: + f() + except RuntimeError, e: + assert str(e) == "maximum recursion depth exceeded" + else: + assert 0, "should have raised!" Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_syntax.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_syntax.py Wed Mar 31 00:17:06 2010 @@ -359,6 +359,22 @@ exec s assert acontext.calls == '__enter__ __exit__'.split() + def test_raw_doc_string(self): + s = """r'doc' +from __future__ import with_statement +class Context(object): + def __enter__(self): + global enter + enter = True + def __exit__(self, *exc): + global exit + exit = True +with Context() as w: + pass""" + exec s + assert enter + assert exit + def test_with_as_var(self): s = """from __future__ import with_statement Modified: pypy/branch/cpython-extension/pypy/interpreter/test/test_zpy.py ============================================================================== --- pypy/branch/cpython-extension/pypy/interpreter/test/test_zpy.py (original) +++ pypy/branch/cpython-extension/pypy/interpreter/test/test_zpy.py Wed Mar 31 00:17:06 2010 @@ -6,17 +6,23 @@ pypypath = py.path.local(pypy.__file__).dirpath("bin", "py.py") +def cmdexec(s): + if sys.platform == 'win32': + s = '"%s"' % s # double double quotes + return py.process.cmdexec(s) + + def test_executable(): """Ensures sys.executable points to the py.py script""" # TODO : watch out for spaces/special chars in pypypath - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % - (sys.executable, pypypath) ) + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.executable" ''' % + (sys.executable, pypypath) ) assert output.splitlines()[-1] == pypypath def test_special_names(): """Test the __name__ and __file__ special global names""" cmd = "print __name__; print '__file__' in globals()" - output = py.process.cmdexec( '''"%s" "%s" -c "%s" ''' % + output = cmdexec( '''"%s" "%s" -c "%s" ''' % (sys.executable, pypypath, cmd) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == 'False' @@ -26,7 +32,7 @@ tmpfile.write("print __name__; print __file__\n") tmpfile.close() - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-2] == '__main__' assert output.splitlines()[-1] == str(tmpfilepath) @@ -34,17 +40,17 @@ def test_argv_command(): """Some tests on argv""" # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" ''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c']) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % + output = cmdexec( '''"%s" "%s" -O -c "import sys;print sys.argv" hello''' % (sys.executable, pypypath) ) assert output.splitlines()[-1] == str(['-c','hello']) @@ -59,17 +65,17 @@ tmpfile.close() # test 1 : no arguments - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath]) # test 2 : some arguments after - output = py.process.cmdexec( '''"%s" "%s" "%s" hello''' % + output = cmdexec( '''"%s" "%s" "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) # test 3 : additionnal pypy parameters - output = py.process.cmdexec( '''"%s" "%s" -O "%s" hello''' % + output = cmdexec( '''"%s" "%s" -O "%s" hello''' % (sys.executable, pypypath, tmpfilepath) ) assert output.splitlines()[-1] == str([tmpfilepath,'hello']) @@ -94,7 +100,7 @@ e = None try: - output = py.process.cmdexec( '''"%s" "%s" "%s" ''' % + output = cmdexec( '''"%s" "%s" "%s" ''' % (sys.executable, pypypath, tmpfilepath) ) except py.process.cmdexec.Error, e: pass Modified: pypy/branch/cpython-extension/pypy/jit/backend/llsupport/descr.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/llsupport/descr.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/llsupport/descr.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,9 @@ -from pypy.rpython.lltypesystem import lltype -from pypy.jit.backend.llsupport import symbolic +import py +from pypy.rpython.lltypesystem import lltype, rffi, llmemory +from pypy.jit.backend.llsupport import symbolic, support from pypy.jit.metainterp.history import AbstractDescr, getkind, BoxInt, BoxPtr from pypy.jit.metainterp.history import BasicFailDescr, LoopToken, BoxFloat +from pypy.jit.metainterp import history from pypy.jit.metainterp.resoperation import ResOperation, rop # The point of the class organization in this file is to make instances @@ -11,8 +13,9 @@ class GcCache(object): - def __init__(self, translate_support_code): + def __init__(self, translate_support_code, rtyper=None): self.translate_support_code = translate_support_code + self.rtyper = rtyper self._cache_size = {} self._cache_field = {} self._cache_array = {} @@ -176,6 +179,7 @@ # CallDescrs class BaseCallDescr(AbstractDescr): + empty_box = BoxInt(0) _clsname = '' loop_token = None arg_classes = '' # <-- annotation hack @@ -187,17 +191,9 @@ def get_extra_info(self): return self.extrainfo - def instantiate_arg_classes(self): - result = [] - for c in self.arg_classes: - if c == 'i': box = BoxInt() - elif c == 'f': box = BoxFloat() - else: box = BoxPtr() - result.append(box) - return result - _returns_a_pointer = False # unless overridden by GcPtrCallDescr _returns_a_float = False # unless overridden by FloatCallDescr + _returns_a_void = False # unless overridden by VoidCallDescr def returns_a_pointer(self): return self._returns_a_pointer @@ -205,39 +201,59 @@ def returns_a_float(self): return self._returns_a_float + def returns_a_void(self): + return self._returns_a_void + def get_result_size(self, translate_support_code): raise NotImplementedError - def get_token_for_call(self, cpu): - if self.loop_token is not None: - return self.loop_token - args = [BoxInt()] + self.instantiate_arg_classes() - if self.get_result_size(cpu.translate_support_code) == 0: - result = None - result_list = [] - else: - if self.returns_a_pointer(): - result = BoxPtr() - elif self.returns_a_float(): - result = BoxFloat() + def get_call_stub(self): + return self.call_stub + + def create_call_stub(self, rtyper, RESULT): + def process(no, c): + if c == 'i': + return 'args[%d].getint()' % (no,) + elif c == 'f': + return 'args[%d].getfloat()' % (no,) + elif c == 'r': + return 'args[%d].getref_base()' % (no,) else: - result = BoxInt() - result_list = [result] - operations = [ - ResOperation(rop.CALL, args[:], result, self), - ResOperation(rop.GUARD_NO_EXCEPTION, [], None, - descr=BasicFailDescr()), - ResOperation(rop.FINISH, result_list, None, - descr=BasicFailDescr())] - operations[1].fail_args = [] - loop_token = LoopToken() - # note: the 'args' that we pass below is not the same object as the - # 'args[:]' that was passed above to ResOperation, because we want - # the argument to ResOperation to be non-resizable, but the argument - # to compile_loop to be resizable. - cpu.compile_loop(args, operations, loop_token) - self.loop_token = loop_token - return loop_token + raise Exception("Unknown type %s for type %s" % (c, TP)) + + def TYPE(arg): + if arg == 'i': + return lltype.Signed + elif arg == 'f': + return lltype.Float + elif arg == 'r': + return llmemory.GCREF + elif arg == 'v': + return lltype.Void + + args = ", ".join([process(i + 1, c) for i, c in + enumerate(self.arg_classes)]) + + if self.returns_a_pointer(): + result = 'history.BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, res))' + elif self.returns_a_float(): + result = 'history.BoxFloat(res)' + elif self.returns_a_void(): + result = 'None' + else: + result = 'history.BoxInt(rffi.cast(lltype.Signed, res))' + source = py.code.Source(""" + def call_stub(args): + fnptr = rffi.cast(lltype.Ptr(FUNC), args[0].getint()) + res = support.maybe_on_top_of_llinterp(rtyper, fnptr)(%(args)s) + return %(result)s + """ % locals()) + ARGS = [TYPE(arg) for arg in self.arg_classes] + FUNC = lltype.FuncType(ARGS, RESULT) + d = locals().copy() + d.update(globals()) + exec source.compile() in d + self.call_stub = d['call_stub'] def repr_of_descr(self): return '<%s>' % self._clsname @@ -245,15 +261,20 @@ class NonGcPtrCallDescr(BaseCallDescr): _clsname = 'NonGcPtrCallDescr' + def get_result_size(self, translate_support_code): return symbolic.get_size_of_ptr(translate_support_code) class GcPtrCallDescr(NonGcPtrCallDescr): + empty_box = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) _clsname = 'GcPtrCallDescr' _returns_a_pointer = True class VoidCallDescr(NonGcPtrCallDescr): + empty_box = None _clsname = 'VoidCallDescr' + _returns_a_void = True + def get_result_size(self, translate_support_code): return 0 @@ -281,6 +302,7 @@ return cache[key] except KeyError: calldescr = cls(arg_classes, extrainfo) + calldescr.create_call_stub(gccache.rtyper, RESULT) cache[key] = calldescr return calldescr @@ -308,6 +330,7 @@ # if TYPE is lltype.Float: setattr(Descr, floatattrname, True) + Descr.empty_box = BoxFloat(0.0) # _cache[nameprefix, TYPE] = Descr return Descr Modified: pypy/branch/cpython-extension/pypy/jit/backend/llsupport/gc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/llsupport/gc.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/llsupport/gc.py Wed Mar 31 00:17:06 2010 @@ -2,6 +2,7 @@ from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.debug import fatalerror from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr +from pypy.rpython.lltypesystem import llgroup from pypy.rpython.lltypesystem.lloperation import llop from pypy.rpython.annlowlevel import llhelper from pypy.translator.tool.cbuild import ExternalCompilationInfo @@ -18,8 +19,8 @@ # ____________________________________________________________ class GcLLDescription(GcCache): - def __init__(self, gcdescr, translator=None): - GcCache.__init__(self, translator is not None) + def __init__(self, gcdescr, translator=None, rtyper=None): + GcCache.__init__(self, translator is not None, rtyper) self.gcdescr = gcdescr def _freeze_(self): return True @@ -40,8 +41,8 @@ moving_gc = False gcrootmap = None - def __init__(self, gcdescr, translator): - GcLLDescription.__init__(self, gcdescr, translator) + def __init__(self, gcdescr, translator, rtyper): + GcLLDescription.__init__(self, gcdescr, translator, rtyper) # grab a pointer to the Boehm 'malloc' function from pypy.rpython.tool import rffi_platform compilation_info = rffi_platform.configure_boehm() @@ -309,7 +310,7 @@ # if convenient for the backend, we also compute the info about # the flag as (byte-offset, single-byte-flag). import struct - value = struct.pack("i", self.jit_wb_if_flag) + value = struct.pack("l", self.jit_wb_if_flag) assert value.count('\x00') == len(value) - 1 # only one byte is != 0 i = 0 while value[i] == '\x00': i += 1 @@ -326,11 +327,11 @@ class GcLLDescr_framework(GcLLDescription): DEBUG = False # forced to True by x86/test/test_zrpy_gc.py - def __init__(self, gcdescr, translator, llop1=llop): + def __init__(self, gcdescr, translator, rtyper, llop1=llop): from pypy.rpython.memory.gctypelayout import _check_typeid from pypy.rpython.memory.gcheader import GCHeaderBuilder from pypy.rpython.memory.gctransform import framework - GcLLDescription.__init__(self, gcdescr, translator) + GcLLDescription.__init__(self, gcdescr, translator, rtyper) assert self.translate_support_code, "required with the framework GC" self.translator = translator self.llop1 = llop1 @@ -372,8 +373,8 @@ # make a malloc function, with three arguments def malloc_basic(size, tid): - type_id = llop.extract_ushort(rffi.USHORT, tid) - has_finalizer = bool(tid & (1<<16)) + type_id = llop.extract_ushort(llgroup.HALFWORD, tid) + has_finalizer = bool(tid & (1< 0: - return BoxInt(self.get_latest_value_int(0)) - else: - return None - + callstub = calldescr.get_call_stub() + try: + return callstub(args) + except Exception, e: + if not we_are_translated(): + if not type(e) is LLException: + raise + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + e.args[1]) + self.saved_exception = rffi.cast(lltype.Signed, e.args[0]) + else: + ptr = cast_instance_to_base_ptr(e) + self.saved_exc_value = lltype.cast_opaque_ptr(llmemory.GCREF, + ptr) + self.saved_exception = rffi.cast(lltype.Signed, ptr.typeptr) + return calldescr.empty_box + def do_cast_ptr_to_int(self, ptrbox): return BoxInt(self.cast_gcref_to_int(ptrbox.getref_base())) Modified: pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_descr.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_descr.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_descr.py Wed Mar 31 00:17:06 2010 @@ -2,7 +2,8 @@ from pypy.jit.backend.llsupport.descr import * from pypy.jit.backend.llsupport import symbolic from pypy.rlib.objectmodel import Symbolic - +from pypy.rpython.annlowlevel import llhelper +from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr def test_get_size_descr(): c0 = GcCache(False) @@ -147,6 +148,7 @@ assert not descr1.returns_a_pointer() assert not descr1.returns_a_float() assert descr1.arg_classes == "ii" + assert isinstance(descr1.empty_box, BoxInt) # T = lltype.GcStruct('T') descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) @@ -154,15 +156,22 @@ assert descr2.returns_a_pointer() assert not descr2.returns_a_float() assert descr2.arg_classes == "r" + assert isinstance(descr2.empty_box, BoxPtr) # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) # + V = lltype.Struct('V', ('x', lltype.Signed)) + assert isinstance(get_call_descr(c0, [], lltype.Ptr(V)).empty_box, BoxInt) + # + assert get_call_descr(c0, [], lltype.Void).empty_box is None + # descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float) assert descr4.get_result_size(False) == rffi.sizeof(lltype.Float) assert not descr4.returns_a_pointer() assert descr4.returns_a_float() assert descr4.arg_classes == "ff" + assert isinstance(descr4.empty_box, BoxFloat) def test_get_call_descr_translated(): c1 = GcCache(True) @@ -227,3 +236,34 @@ # descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float) assert 'FloatCallDescr' in descr4f.repr_of_descr() + +def test_call_stubs(): + c0 = GcCache(False) + ARGS = [lltype.Char, lltype.Signed] + RES = lltype.Char + descr1 = get_call_descr(c0, ARGS, RES) + def f(a, b): + return 'c' + + call_stub = descr1.get_call_stub() + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + + res = call_stub([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxInt(1), BoxInt(2)]) + assert res.getint() == ord('c') + + ARRAY = lltype.GcArray(lltype.Signed) + ARGS = [lltype.Float, lltype.Ptr(ARRAY)] + RES = lltype.Float + + def f(a, b): + return float(b[0]) + a + + fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) + descr2 = get_call_descr(c0, ARGS, RES) + a = lltype.malloc(ARRAY, 3) + opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) + a[0] = 1 + res = descr2.get_call_stub()([BoxInt(rffi.cast(lltype.Signed, fnptr)), + BoxFloat(3.5), BoxPtr(opaquea)]) + assert res.getfloat() == 4.5 Modified: pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_gc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_gc.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/llsupport/test/test_gc.py Wed Mar 31 00:17:06 2010 @@ -9,7 +9,7 @@ def test_boehm(): - gc_ll_descr = GcLLDescr_boehm(None, None) + gc_ll_descr = GcLLDescr_boehm(None, None, None) # record = [] prev_funcptr_for_new = gc_ll_descr.funcptr_for_new @@ -167,7 +167,8 @@ gcdescr = get_description(config_) translator = FakeTranslator() llop1 = FakeLLOp() - gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), llop1) + gc_ll_descr = GcLLDescr_framework(gcdescr, FakeTranslator(), None, + llop1) gc_ll_descr.initialize() self.llop1 = llop1 self.gc_ll_descr = gc_ll_descr Modified: pypy/branch/cpython-extension/pypy/jit/backend/x86/assembler.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/x86/assembler.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/x86/assembler.py Wed Mar 31 00:17:06 2010 @@ -1000,15 +1000,18 @@ # we use the following algorithm: # - read the typeid from mem(locs[0]), i.e. at offset 0 # - keep the lower 16 bits read there - # - multiply by 4 and use it as an offset in type_info_group. + # - multiply by 4 and use it as an offset in type_info_group + # - add 16 bytes, to go past the TYPE_INFO structure loc = locs[1] assert isinstance(loc, IMM32) classptr = loc.value # here, we have to go back from 'classptr' to the value expected # from reading the 16 bits in the object header + from pypy.rpython.memory.gctypelayout import GCData + sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) - expected_typeid = (classptr - type_info_group) >> 2 + expected_typeid = (classptr - sizeof_ti - type_info_group) >> 2 mc.CMP16(mem(locs[0], 0), imm32(expected_typeid)) def genop_guard_guard_class(self, ign_1, guard_op, addr, locs, ign_2): Modified: pypy/branch/cpython-extension/pypy/jit/backend/x86/runner.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/x86/runner.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/x86/runner.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,3 @@ -import sys -import ctypes -import py from pypy.rpython.lltypesystem import lltype, llmemory, rffi from pypy.rpython.llinterp import LLInterpreter from pypy.rlib.objectmodel import we_are_translated Modified: pypy/branch/cpython-extension/pypy/jit/backend/x86/test/conftest.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/x86/test/conftest.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/x86/test/conftest.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,9 @@ import py from pypy.jit.backend import detect_cpu -class Directory(py.test.collect.Directory): +class Module(py.test.collect.Module): def collect(self): cpu = detect_cpu.autodetect() if cpu != 'x86': py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) - return super(Directory, self).collect() + return super(Module, self).collect() Modified: pypy/branch/cpython-extension/pypy/jit/backend/x86/test/test_ztranslation.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/x86/test/test_ztranslation.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/x86/test/test_ztranslation.py Wed Mar 31 00:17:06 2010 @@ -1,10 +1,12 @@ -import py +import py, os +from pypy.tool.udir import udir from pypy.rlib.jit import JitDriver, OPTIMIZER_FULL, unroll_parameters from pypy.rlib.jit import PARAMETERS, dont_look_inside from pypy.jit.metainterp.jitprof import Profiler from pypy.jit.backend.x86.runner import CPU386 from pypy.jit.backend.test.support import CCompiledMixin from pypy.jit.metainterp.policy import StopAtXPolicy +from pypy.translator.translator import TranslationContext class TestTranslationX86(CCompiledMixin): CPUClass = CPU386 @@ -62,40 +64,6 @@ res = self.meta_interp(f, [40, -49]) assert res == f(40, -49) - def test_external_exception_handling_translates(self): - jitdriver = JitDriver(greens = [], reds = ['n', 'total']) - - @dont_look_inside - def f(x): - if x > 20: - return 2 - raise ValueError - @dont_look_inside - def g(x): - if x > 15: - raise ValueError - return 2 - def main(i): - jitdriver.set_param("threshold", 3) - jitdriver.set_param("trace_eagerness", 2) - total = 0 - n = i - while n > 3: - jitdriver.can_enter_jit(n=n, total=total) - jitdriver.jit_merge_point(n=n, total=total) - try: - total += f(n) - except ValueError: - total += 1 - try: - total += g(n) - except ValueError: - total -= 1 - n -= 1 - return total * 10 - res = self.meta_interp(main, [40]) - assert res == main(40) - def test_direct_assembler_call_translates(self): class Thing(object): def __init__(self, val): @@ -144,3 +112,75 @@ policy=StopAtXPolicy(change)) assert res == main(0) + +class TestTranslationRemoveTypePtrX86(CCompiledMixin): + CPUClass = CPU386 + + def _get_TranslationContext(self): + t = TranslationContext() + t.config.translation.gc = 'hybrid' + t.config.translation.gcrootfinder = 'asmgcc' + t.config.translation.list_comprehension_operations = True + t.config.translation.gcremovetypeptr = True + return t + + def test_external_exception_handling_translates(self): + jitdriver = JitDriver(greens = [], reds = ['n', 'total']) + + @dont_look_inside + def f(x): + if x > 20: + return 2 + raise ValueError + @dont_look_inside + def g(x): + if x > 15: + raise ValueError + return 2 + class Base: + def meth(self): + return 2 + class Sub(Base): + def meth(self): + return 1 + @dont_look_inside + def h(x): + if x < 2000: + return Sub() + else: + return Base() + def main(i): + jitdriver.set_param("threshold", 3) + jitdriver.set_param("trace_eagerness", 2) + total = 0 + n = i + while n > 3: + jitdriver.can_enter_jit(n=n, total=total) + jitdriver.jit_merge_point(n=n, total=total) + try: + total += f(n) + except ValueError: + total += 1 + try: + total += g(n) + except ValueError: + total -= 1 + n -= h(n).meth() # this is to force a GUARD_CLASS + return total * 10 + + # XXX custom fishing, depends on the exact env var and format + logfile = udir.join('test_ztranslation.log') + os.environ['PYPYLOG'] = 'jit-log-opt:%s' % (logfile,) + try: + res = self.meta_interp(main, [40]) + assert res == main(40) + finally: + del os.environ['PYPYLOG'] + + guard_class = 0 + for line in open(str(logfile)): + if 'guard_class' in line: + guard_class += 1 + # if we get many more guard_classes, it means that we generate + # guards that always fail + assert 0 < guard_class <= 4 Modified: pypy/branch/cpython-extension/pypy/jit/backend/x86/tool/viewcode.py ============================================================================== --- pypy/branch/cpython-extension/pypy/jit/backend/x86/tool/viewcode.py (original) +++ pypy/branch/cpython-extension/pypy/jit/backend/x86/tool/viewcode.py Wed Mar 31 00:17:06 2010 @@ -34,7 +34,8 @@ def machine_code_dump(data, originaddr): # the disassembler to use. 'objdump' writes GNU-style instructions. # 'ndisasm' would use Intel syntax, but you need to fix the output parsing. - objdump = 'objdump -b binary -m i386 --adjust-vma=%(origin)d -D %(file)s' + objdump = ('objdump -M intel -b binary -m i386 ' + '--adjust-vma=%(origin)d -D %(file)s') # f = open(tmpfile, 'wb') f.write(data) Modified: pypy/branch/cpython-extension/pypy/lib/_ctypes/function.py ============================================================================== --- pypy/branch/cpython-extension/pypy/lib/_ctypes/function.py (original) +++ pypy/branch/cpython-extension/pypy/lib/_ctypes/function.py Wed Mar 31 00:17:06 2010 @@ -359,6 +359,9 @@ # No output parameter, return the actual function result. return retval + def __nonzero__(self): + return bool(self._buffer[0]) + def __del__(self): if self._needs_free: # XXX we need to find a bad guy here Modified: pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_cast.py ============================================================================== --- pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_cast.py (original) +++ pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_cast.py Wed Mar 31 00:17:06 2010 @@ -84,4 +84,6 @@ my_sqrt = lib.my_sqrt sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double)) assert sqrt(4.0) == 2.0 + assert not cast(0, CFUNCTYPE(c_int)) + Modified: pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_funcptr.py ============================================================================== --- pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_funcptr.py (original) +++ pypy/branch/cpython-extension/pypy/lib/app_test/ctypes_tests/test_funcptr.py Wed Mar 31 00:17:06 2010 @@ -131,6 +131,8 @@ assert strtok(None, "\n") == None def test_from_address(self): + py.test.skip("This test needs mmap to make sure the" + " code is executable, please rewrite me") def make_function(): proto = CFUNCTYPE(c_int) a=create_string_buffer( Modified: pypy/branch/cpython-extension/pypy/lib/app_test/test_dbm_extra.py ============================================================================== --- pypy/branch/cpython-extension/pypy/lib/app_test/test_dbm_extra.py (original) +++ pypy/branch/cpython-extension/pypy/lib/app_test/test_dbm_extra.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,9 @@ import py -from pypy.lib import dbm from pypy.tool.udir import udir +try: + from pypy.lib import dbm +except ImportError, e: + py.test.skip(e) def test_get(): path = str(udir.join('test_dbm_extra.test_get')) Modified: pypy/branch/cpython-extension/pypy/lib/resource.py ============================================================================== --- pypy/branch/cpython-extension/pypy/lib/resource.py (original) +++ pypy/branch/cpython-extension/pypy/lib/resource.py Wed Mar 31 00:17:06 2010 @@ -28,8 +28,8 @@ class timeval(Structure): _fields_ = ( - ("tv_sec", c_int), - ("tv_usec", c_int), + ("tv_sec", c_long), + ("tv_usec", c_long), ) def __str__(self): return "(%s, %s)" % (self.tv_sec, self.tv_usec) Modified: pypy/branch/cpython-extension/pypy/module/__pypy__/interp_magic.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/__pypy__/interp_magic.py (original) +++ pypy/branch/cpython-extension/pypy/module/__pypy__/interp_magic.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace from pypy.rlib.objectmodel import we_are_translated +from pypy.objspace.std.typeobject import MethodCache def internal_repr(space, w_object): return space.wrap('%r' % (w_object,)) @@ -24,13 +25,15 @@ """Return a tuple (method_cache_hits, method_cache_misses) for calls to methods with the name.""" assert space.config.objspace.std.withmethodcachecounter - return space.newtuple([space.newint(space.method_cache_hits.get(name, 0)), - space.newint(space.method_cache_misses.get(name, 0)),]) + cache = space.fromcache(MethodCache) + return space.newtuple([space.newint(cache.hits.get(name, 0)), + space.newint(cache.misses.get(name, 0))]) method_cache_counter.unwrap_spec = [ObjSpace, str] def reset_method_cache_counter(space): """Reset the method cache counter to zero for all method names.""" assert space.config.objspace.std.withmethodcachecounter - space.method_cache_misses = {} - space.method_cache_hits = {} + cache = space.fromcache(MethodCache) + cache.misses = {} + cache.hits = {} Modified: pypy/branch/cpython-extension/pypy/module/_file/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_file/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/_file/__init__.py Wed Mar 31 00:17:06 2010 @@ -24,8 +24,8 @@ MixedModule.__init__(self, space, *args) def shutdown(self, space): - # at shutdown, flush all open streams - from pypy.module._file.interp_file import getopenstreams + # at shutdown, flush all open streams. Ignore I/O errors. + from pypy.module._file.interp_file import getopenstreams, StreamErrors openstreams = getopenstreams(space) while openstreams: for stream in openstreams.keys(): @@ -34,7 +34,10 @@ except KeyError: pass # key was removed in the meantime else: - stream.flush() + try: + stream.flush() + except StreamErrors: + pass def setup_after_space_initialization(self): from pypy.module._file.interp_file import W_File Modified: pypy/branch/cpython-extension/pypy/module/_minimal_curses/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_minimal_curses/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/_minimal_curses/__init__.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,10 @@ try: import _curses except ImportError: - import _minimal_curses as _curses # when running on top of pypy-c + try: + import _minimal_curses as _curses # when running on top of pypy-c + except ImportError: + import py; py.test.skip("no _curses module") # no _curses at all from pypy.interpreter.mixedmodule import MixedModule from pypy.module._minimal_curses import fficurses Modified: pypy/branch/cpython-extension/pypy/module/_socket/interp_func.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_socket/interp_func.py (original) +++ pypy/branch/cpython-extension/pypy/module/_socket/interp_func.py Wed Mar 31 00:17:06 2010 @@ -2,6 +2,7 @@ from pypy.module._socket.interp_socket import converted_error, W_RSocket from pypy.rlib import rsocket from pypy.rlib.rsocket import SocketError +from pypy.rlib.rarithmetic import r_uint from pypy.interpreter.error import OperationError, operationerrfmt def gethostname(space): @@ -152,30 +153,24 @@ return space.newtuple([space.wrap(sock1), space.wrap(sock2)]) socketpair.unwrap_spec = [ObjSpace, int, int, int] +# The following 4 functions refuse all negative numbers, like CPython 2.6. +# They could also check that the argument is not too large, but CPython 2.6 +# is not doing that consistently. def ntohs(space, x): """ntohs(integer) -> integer Convert a 16-bit integer from network to host byte order. """ return space.wrap(rsocket.ntohs(x)) -ntohs.unwrap_spec = [ObjSpace, int] +ntohs.unwrap_spec = [ObjSpace, r_uint] -def ntohl(space, w_x): +def ntohl(space, x): """ntohl(integer) -> integer Convert a 32-bit integer from network to host byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.ntohl(x)) -ntohl.unwrap_spec = [ObjSpace, W_Root] +ntohl.unwrap_spec = [ObjSpace, r_uint] def htons(space, x): """htons(integer) -> integer @@ -183,24 +178,15 @@ Convert a 16-bit integer from host to network byte order. """ return space.wrap(rsocket.htons(x)) -htons.unwrap_spec = [ObjSpace, int] +htons.unwrap_spec = [ObjSpace, r_uint] -def htonl(space, w_x): +def htonl(space, x): """htonl(integer) -> integer Convert a 32-bit integer from host to network byte order. """ - if space.is_true(space.isinstance(w_x, space.w_int)): - x = space.int_w(w_x) - elif space.is_true(space.isinstance(w_x, space.w_long)): - x = space.uint_w(w_x) - else: - raise operationerrfmt(space.w_TypeError, - "expected int/long, %s found", - space.type(w_x).getname(space, "?")) - return space.wrap(rsocket.htonl(x)) -htonl.unwrap_spec = [ObjSpace, W_Root] +htonl.unwrap_spec = [ObjSpace, r_uint] def inet_aton(space, ip): """inet_aton(string) -> packed 32-bit IP representation Modified: pypy/branch/cpython-extension/pypy/module/_socket/test/test_sock_app.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_socket/test/test_sock_app.py (original) +++ pypy/branch/cpython-extension/pypy/module/_socket/test/test_sock_app.py Wed Mar 31 00:17:06 2010 @@ -32,13 +32,17 @@ def test_gethostbyaddr(): host = "localhost" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds host = "127.0.0.1" + expected = socket.gethostbyaddr(host) + expecteds = (expected, expected[:2]+(['0.0.0.0'],)) ip = space.appexec([w_socket, space.wrap(host)], "(_socket, host): return _socket.gethostbyaddr(host)") - assert space.unwrap(ip) == socket.gethostbyaddr(host) + assert space.unwrap(ip) in expecteds def test_getservbyname(): name = "smtp" @@ -108,6 +112,9 @@ w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.ntohl(x)") assert space.unwrap(w_n) == socket.ntohl(125) + w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], + "(_socket, x): return _socket.ntohl(x)") + assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) def test_htons(): w_n = space.appexec([w_socket, space.wrap(125)], @@ -118,6 +125,9 @@ w_n = space.appexec([w_socket, space.wrap(125)], "(_socket, x): return _socket.htonl(x)") assert space.unwrap(w_n) == socket.htonl(125) + w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], + "(_socket, x): return _socket.htonl(x)") + assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) def test_aton_ntoa(): ip = '123.45.67.89' @@ -314,9 +324,12 @@ import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) # XXX temporarily we use codespeak to test, will have more robust tests in - # the absence of a network connection later when mroe parts of the socket - # API are implemented. - s.connect(("codespeak.net", 80)) + # the absence of a network connection later when more parts of the socket + # API are implemented. currently skip the test if there is no connection. + try: + s.connect(("codespeak.net", 80)) + except _socket.gaierror, ex: + skip("GAIError - probably no connection: %s" % str(ex.args)) name = s.getpeername() # Will raise socket.error if not connected assert name[1] == 80 s.close() @@ -335,6 +348,7 @@ s.close() def test_NtoH(self): + import sys import _socket as socket # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. @@ -348,7 +362,28 @@ swapped = func(mask) assert swapped & mask == mask try: - func(1L<<34) + func(-1) + except (OverflowError, ValueError): + pass + else: + assert False + try: + func(sys.maxint*2+2) + except OverflowError: + pass + else: + assert False + + def test_NtoH_overflow(self): + skip("we are not checking for overflowing values yet") + import _socket as socket + # Checks that we cannot give too large values to htons etc. + # Skipped for now; CPython 2.6 is also not consistent. + sizes = {socket.htonl: 32, socket.ntohl: 32, + socket.htons: 16, socket.ntohs: 16} + for func, size in sizes.items(): + try: + func(1L << size) except OverflowError: pass else: @@ -399,9 +434,12 @@ import _socket, os s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) # XXX temporarily we use codespeak to test, will have more robust tests in - # the absence of a network connection later when mroe parts of the socket - # API are implemented. - s.connect(("codespeak.net", 80)) + # the absence of a network connection later when more parts of the socket + # API are implemented. currently skip the test if there is no connection. + try: + s.connect(("codespeak.net", 80)) + except _socket.gaierror, ex: + skip("GAIError - probably no connection: %s" % str(ex.args)) s.send(buffer('')) s.sendall(buffer('')) s.send(u'') Modified: pypy/branch/cpython-extension/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_sre/interp_sre.py (original) +++ pypy/branch/cpython-extension/pypy/module/_sre/interp_sre.py Wed Mar 31 00:17:06 2010 @@ -177,10 +177,20 @@ state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.search(pattern_codes)) + try: + res = state.search(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) def w_match(space, w_state, w_pattern_codes): state = space.interp_w(W_State, w_state) pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] - return space.newbool(state.match(pattern_codes)) + try: + res = state.match(pattern_codes) + except RuntimeError: + raise OperationError(space.w_RuntimeError, + space.wrap("Internal re error")) + return space.newbool(res) Modified: pypy/branch/cpython-extension/pypy/module/_weakref/interp__weakref.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_weakref/interp__weakref.py (original) +++ pypy/branch/cpython-extension/pypy/module/_weakref/interp__weakref.py Wed Mar 31 00:17:06 2010 @@ -23,7 +23,7 @@ for i in range(len(self.refs_weak) - 1, -1, -1): w_ref = self.refs_weak[i]() if w_ref is not None: - w_ref.activate_callback() + self.space.user_del_action.register_weakref_callback(w_ref) def clear_all_weakrefs(self): """Clear all weakrefs. This is called when an app-level object has Modified: pypy/branch/cpython-extension/pypy/module/_weakref/test/test_weakref.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/_weakref/test/test_weakref.py (original) +++ pypy/branch/cpython-extension/pypy/module/_weakref/test/test_weakref.py Wed Mar 31 00:17:06 2010 @@ -411,3 +411,15 @@ a = A() assert _weakref.ref(a) == a + + def test_callback_raises(self): + import _weakref, gc + class A(object): + pass + a1 = A() + def callback(ref): + explode + ref1 = _weakref.ref(a1, callback) + del a1 + gc.collect() + assert ref1() is None Modified: pypy/branch/cpython-extension/pypy/module/imp/importing.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/imp/importing.py (original) +++ pypy/branch/cpython-extension/pypy/module/imp/importing.py Wed Mar 31 00:17:06 2010 @@ -324,6 +324,7 @@ modtype, suffix, filemode = find_modtype(space, filepart) try: if modtype in (PY_SOURCE, PY_COMPILED): + assert suffix is not None filename = filepart + suffix stream = streamio.open_file_as_stream(filename, filemode) try: Modified: pypy/branch/cpython-extension/pypy/module/mmap/interp_mmap.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/mmap/interp_mmap.py (original) +++ pypy/branch/cpython-extension/pypy/module/mmap/interp_mmap.py Wed Mar 31 00:17:06 2010 @@ -57,7 +57,8 @@ try: return self.space.wrap(self.mmap.file_size()) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') descr_size.unwrap_spec = ['self'] def write(self, data): @@ -87,7 +88,8 @@ raise OperationError(self.space.w_ValueError, self.space.wrap(v.message)) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') flush.unwrap_spec = ['self', int, int] def move(self, dest, src, count): @@ -104,7 +106,8 @@ try: self.mmap.resize(newsize) except OSError, e: - raise wrap_oserror(self.space, e, 'w_EnvironmentError') + raise wrap_oserror(self.space, e, + exception_name='w_EnvironmentError') resize.unwrap_spec = ['self', int] def __len__(self): @@ -224,7 +227,7 @@ return space.wrap(W_MMap(space, rmmap.mmap(fileno, length, flags, prot, access))) except OSError, e: - raise wrap_oserror(space, e, 'w_EnvironmentError') + raise wrap_oserror(space, e, exception_name='w_EnvironmentError') except RValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.message)) except RTypeError, e: @@ -238,7 +241,7 @@ return space.wrap(W_MMap(space, rmmap.mmap(fileno, length, tagname, access))) except OSError, e: - raise wrap_oserror(space, e, 'w_EnvironmentError') + raise wrap_oserror(space, e, exception_name='w_EnvironmentError') except RValueError, e: raise OperationError(space.w_ValueError, space.wrap(e.message)) except RTypeError, e: Modified: pypy/branch/cpython-extension/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/posix/interp_posix.py (original) +++ pypy/branch/cpython-extension/pypy/module/posix/interp_posix.py Wed Mar 31 00:17:06 2010 @@ -18,9 +18,9 @@ try: fd = os.open(fname, flag, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, fname) return space.wrap(fd) -open.unwrap_spec = [ObjSpace, str, int, int] +open.unwrap_spec = [ObjSpace, str, "c_int", "c_int"] def lseek(space, fd, pos, how): """Set the current position of a file descriptor. Return the new position. @@ -32,7 +32,7 @@ raise wrap_oserror(space, e) else: return space.wrap(pos) -lseek.unwrap_spec = [ObjSpace, int, r_longlong, int] +lseek.unwrap_spec = [ObjSpace, "c_int", r_longlong, "c_int"] def isatty(space, fd): """Return True if 'fd' is an open file descriptor connected to the @@ -43,7 +43,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -isatty.unwrap_spec = [ObjSpace, int] +isatty.unwrap_spec = [ObjSpace, "c_int"] def read(space, fd, buffersize): """Read data from a file descriptor.""" @@ -53,7 +53,7 @@ raise wrap_oserror(space, e) else: return space.wrap(s) -read.unwrap_spec = [ObjSpace, int, int] +read.unwrap_spec = [ObjSpace, "c_int", int] def write(space, fd, data): """Write a string to a file descriptor. Return the number of bytes @@ -64,7 +64,7 @@ raise wrap_oserror(space, e) else: return space.wrap(res) -write.unwrap_spec = [ObjSpace, int, 'bufferstr'] +write.unwrap_spec = [ObjSpace, "c_int", 'bufferstr'] def close(space, fd): """Close a file descriptor (for low level IO).""" @@ -72,12 +72,12 @@ os.close(fd) except OSError, e: raise wrap_oserror(space, e) -close.unwrap_spec = [ObjSpace, int] +close.unwrap_spec = [ObjSpace, "c_int"] def closerange(fd_low, fd_high): """Closes all file descriptors in [fd_low, fd_high), ignoring errors.""" rposix.closerange(fd_low, fd_high) -closerange.unwrap_spec = [int, int] +closerange.unwrap_spec = ["c_int", "c_int"] def ftruncate(space, fd, length): """Truncate a file to a specified length.""" @@ -85,21 +85,21 @@ os.ftruncate(fd, length) except OSError, e: raise wrap_oserror(space, e) -ftruncate.unwrap_spec = [ObjSpace, int, r_longlong] +ftruncate.unwrap_spec = [ObjSpace, "c_int", r_longlong] def fsync(space, fd): try: os.fsync(fd) except OSError, e: raise wrap_oserror(space, e) -fsync.unwrap_spec = [ObjSpace, int] +fsync.unwrap_spec = [ObjSpace, "c_int"] def fdatasync(space, fd): try: os.fdatasync(fd) except OSError, e: raise wrap_oserror(space, e) -fdatasync.unwrap_spec = [ObjSpace, int] +fdatasync.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -157,7 +157,7 @@ raise wrap_oserror(space, e) else: return build_stat_result(space, st) -fstat.unwrap_spec = [ObjSpace, int] +fstat.unwrap_spec = [ObjSpace, "c_int"] def stat(space, path): """Perform a stat system call on the given path. Return an object @@ -177,7 +177,7 @@ try: st = os.stat(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) else: return build_stat_result(space, st) stat.unwrap_spec = [ObjSpace, str] @@ -187,7 +187,7 @@ try: st = os.lstat(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) else: return build_stat_result(space, st) lstat.unwrap_spec = [ObjSpace, str] @@ -221,7 +221,7 @@ raise wrap_oserror(space, e) else: return space.wrap(newfd) -dup.unwrap_spec = [ObjSpace, int] +dup.unwrap_spec = [ObjSpace, "c_int"] def dup2(space, old_fd, new_fd): """Duplicate a file descriptor.""" @@ -229,7 +229,7 @@ os.dup2(old_fd, new_fd) except OSError, e: raise wrap_oserror(space, e) -dup2.unwrap_spec = [ObjSpace, int, int] +dup2.unwrap_spec = [ObjSpace, "c_int", "c_int"] def access(space, path, mode): """ @@ -244,10 +244,10 @@ try: ok = os.access(path, mode) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) else: return space.wrap(ok) -access.unwrap_spec = [ObjSpace, str, int] +access.unwrap_spec = [ObjSpace, str, "c_int"] def times(space): @@ -283,7 +283,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) unlink.unwrap_spec = [ObjSpace, str] def remove(space, path): @@ -291,7 +291,7 @@ try: os.unlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) remove.unwrap_spec = [ObjSpace, str] def _getfullpathname(space, path): @@ -300,7 +300,7 @@ try: fullpath = posix._getfullpathname(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) else: return space.wrap(fullpath) _getfullpathname.unwrap_spec = [ObjSpace, str] @@ -326,7 +326,7 @@ try: os.chdir(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) chdir.unwrap_spec = [ObjSpace, str] def mkdir(space, path, mode=0777): @@ -334,15 +334,15 @@ try: os.mkdir(path, mode) except OSError, e: - raise wrap_oserror(space, e) -mkdir.unwrap_spec = [ObjSpace, str, int] + raise wrap_oserror(space, e, path) +mkdir.unwrap_spec = [ObjSpace, str, "c_int"] def rmdir(space, path): """Remove a directory.""" try: os.rmdir(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) rmdir.unwrap_spec = [ObjSpace, str] def strerror(space, errno): @@ -353,7 +353,7 @@ raise OperationError(space.w_ValueError, space.wrap("strerror() argument out of range")) return space.wrap(text) -strerror.unwrap_spec = [ObjSpace, int] +strerror.unwrap_spec = [ObjSpace, "c_int"] # ____________________________________________________________ @@ -420,7 +420,7 @@ try: result = os.listdir(dirname) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, dirname) result_w = [space.wrap(s) for s in result] return space.newlist(result_w) listdir.unwrap_spec = [ObjSpace, str] @@ -439,8 +439,8 @@ try: os.chmod(path, mode) except OSError, e: - raise wrap_oserror(space, e) -chmod.unwrap_spec = [ObjSpace, str, int] + raise wrap_oserror(space, e, path) +chmod.unwrap_spec = [ObjSpace, str, "c_int"] def rename(space, old, new): "Rename a file or directory." @@ -454,7 +454,7 @@ "Set the current numeric umask and return the previous umask." prevmask = os.umask(mask) return space.wrap(prevmask) -umask.unwrap_spec = [ObjSpace, int] +umask.unwrap_spec = [ObjSpace, "c_int"] def getpid(space): "Return the current process id." @@ -471,7 +471,7 @@ os.kill(pid, sig) except OSError, e: raise wrap_oserror(space, e) -kill.unwrap_spec = [ObjSpace, int, int] +kill.unwrap_spec = [ObjSpace, "c_int", "c_int"] def abort(space): """Abort the interpreter immediately. This 'dumps core' or otherwise fails @@ -501,12 +501,11 @@ try: result = os.readlink(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) return space.wrap(result) readlink.unwrap_spec = [ObjSpace, str] def fork(space): - try: pid = os.fork() except OSError, e: @@ -531,11 +530,11 @@ except OSError, e: raise wrap_oserror(space, e) return space.newtuple([space.wrap(pid), space.wrap(status)]) -waitpid.unwrap_spec = [ObjSpace, int, int] +waitpid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def _exit(space, status): os._exit(status) -_exit.unwrap_spec = [ObjSpace, int] +_exit.unwrap_spec = [ObjSpace, "c_int"] def execv(space, command, w_args): """ execv(path, args) @@ -589,7 +588,7 @@ os.utime(path, None) return except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) try: msg = "utime() arg 2 must be a tuple (atime, mtime) or None" args_w = space.fixedview(w_tuple) @@ -599,7 +598,7 @@ modtime = space.float_w(args_w[1]) os.utime(path, (actime, modtime)) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) except OperationError, e: if not e.match(space, space.w_TypeError): raise @@ -649,7 +648,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setuid.unwrap_spec = [ObjSpace, int] +setuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def seteuid(space, arg): """ seteuid(uid) @@ -661,7 +660,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -seteuid.unwrap_spec = [ObjSpace, int] +seteuid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setgid(space, arg): """ setgid(gid) @@ -673,7 +672,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setgid.unwrap_spec = [ObjSpace, int] +setgid.unwrap_spec = [ObjSpace, "c_nonnegint"] def setegid(space, arg): """ setegid(gid) @@ -685,7 +684,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setegid.unwrap_spec = [ObjSpace, int] +setegid.unwrap_spec = [ObjSpace, "c_nonnegint"] def chroot(space, path): """ chroot(path) @@ -695,7 +694,7 @@ try: os.chroot(path) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) return space.w_None chroot.unwrap_spec = [ObjSpace, str] @@ -761,7 +760,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(pgid) -getpgid.unwrap_spec = [ObjSpace, int] +getpgid.unwrap_spec = [ObjSpace, "c_int"] def setpgid(space, pid, pgrp): """ setpgid(pid, pgrp) @@ -773,7 +772,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setpgid.unwrap_spec = [ObjSpace, int, int] +setpgid.unwrap_spec = [ObjSpace, "c_int", "c_int"] def setreuid(space, ruid, euid): """ setreuid(ruid, euid) @@ -785,7 +784,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setreuid.unwrap_spec = [ObjSpace, int, int] +setreuid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def setregid(space, rgid, egid): """ setregid(rgid, egid) @@ -797,7 +796,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.w_None -setregid.unwrap_spec = [ObjSpace, int, int] +setregid.unwrap_spec = [ObjSpace, "c_nonnegint", "c_nonnegint"] def getsid(space, pid): """ getsid(pid) -> sid @@ -809,7 +808,7 @@ except OSError, e: raise wrap_oserror(space, e) return space.wrap(sid) -getsid.unwrap_spec = [ObjSpace, int] +getsid.unwrap_spec = [ObjSpace, "c_int"] def setsid(space): """ setsid() @@ -831,7 +830,7 @@ def WSTAR(space, status): return space.newbool(getattr(os, name)(status)) WSTAR.__doc__ = getattr(os, name).__doc__ - WSTAR.unwrap_spec = [ObjSpace, int] + WSTAR.unwrap_spec = [ObjSpace, "c_int"] WSTAR.func_name = name return WSTAR @@ -845,7 +844,7 @@ return space.wrap(os.ttyname(fd)) except OSError, e: raise wrap_oserror(space, e) -ttyname.unwrap_spec = [ObjSpace, int] +ttyname.unwrap_spec = [ObjSpace, "c_int"] def sysconf(space, w_num_or_name): # XXX slightly non-nice, reuses the sysconf of the underlying os module @@ -864,9 +863,9 @@ try: os.chown(path, uid, gid) except OSError, e: - raise wrap_oserror(space, e) + raise wrap_oserror(space, e, path) return space.w_None -chown.unwrap_spec = [ObjSpace, str, int, int] +chown.unwrap_spec = [ObjSpace, str, "c_nonnegint", "c_nonnegint"] if _WIN: from pypy.rlib import rwin32 Modified: pypy/branch/cpython-extension/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/posix/test/test_posix2.py (original) +++ pypy/branch/cpython-extension/pypy/module/posix/test/test_posix2.py Wed Mar 31 00:17:06 2010 @@ -133,18 +133,27 @@ assert st.st_mtime == 42.1 assert st.st_ctime == 43 + def test_stat_lstat(self): + import stat + st = self.posix.stat(".") + assert stat.S_ISDIR(st.st_mode) + st = self.posix.lstat(".") + assert stat.S_ISDIR(st.st_mode) + def test_stat_exception(self): import sys, errno - try: - self.posix.stat("nonexistentdir/nonexistentfile") - except OSError, e: - assert e.errno == errno.ENOENT - # On Windows, when the parent directory does not exist, - # the winerror is 3 (cannot find the path specified) - # instead of 2 (cannot find the file specified) - if sys.platform == 'win32': - assert isinstance(e, WindowsError) - assert e.winerror == 3 + for fn in [self.posix.stat, self.posix.lstat]: + try: + fn("nonexistentdir/nonexistentfile") + except OSError, e: + assert e.errno == errno.ENOENT + assert e.filename == "nonexistentdir/nonexistentfile" + # On Windows, when the parent directory does not exist, + # the winerror is 3 (cannot find the path specified) + # instead of 2 (cannot find the file specified) + if sys.platform == 'win32': + assert isinstance(e, WindowsError) + assert e.winerror == 3 def test_pickle(self): import pickle, os @@ -160,11 +169,48 @@ posix = self.posix try: posix.open('qowieuqwoeiu', 0, 0) - except OSError: - pass + except OSError, e: + assert e.filename == 'qowieuqwoeiu' else: assert 0 + def test_filename_exception(self): + for fn in [self.posix.unlink, self.posix.remove, + self.posix.chdir, self.posix.mkdir, self.posix.rmdir, + self.posix.listdir, self.posix.readlink, + self.posix.chroot]: + try: + fn('qowieuqw/oeiu') + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_chmod_exception(self): + try: + self.posix.chmod('qowieuqw/oeiu', 0) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_chown_exception(self): + try: + self.posix.chown('qowieuqw/oeiu', 0, 0) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + + def test_utime_exception(self): + for arg in [None, (0, 0)]: + try: + self.posix.utime('qowieuqw/oeiu', arg) + except OSError, e: + assert e.filename == 'qowieuqw/oeiu' + else: + assert 0 + def test_functions_raise_error(self): def ex(func, *args): try: @@ -309,7 +355,8 @@ os = self.posix for i in range(5): stream = os.popen('echo 1') - assert stream.read() == '1\n' + res = stream.read() + assert res == '1\n' stream.close() if hasattr(__import__(os.name), '_getfullpathname'): @@ -380,7 +427,7 @@ if hasattr(os, 'setuid'): def test_os_setuid_error(self): os = self.posix - raises(OSError, os.setuid, -100000) + raises((OSError, ValueError, OverflowError), os.setuid, -100000) if hasattr(os, 'getgid'): def test_os_getgid(self): @@ -396,13 +443,13 @@ if hasattr(os, 'setgid'): def test_os_setgid_error(self): os = self.posix - raises(OSError, os.setgid, -100000) + raises((OSError, ValueError, OverflowError), os.setgid, -100000) if hasattr(os, 'getsid'): def test_os_getsid(self): os = self.posix assert os.getsid(0) == self.getsid0 - raises(OSError, os.getsid, -100000) + raises((OSError, ValueError, OverflowError), os.getsid, -100000) if hasattr(os, 'sysconf'): def test_os_sysconf(self): Modified: pypy/branch/cpython-extension/pypy/module/pyexpat/test/test_build.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/pyexpat/test/test_build.py (original) +++ pypy/branch/cpython-extension/pypy/module/pyexpat/test/test_build.py Wed Mar 31 00:17:06 2010 @@ -4,8 +4,12 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.tool.rffi_platform import CompilationError -import os, pyexpat +import os import py +try: + import pyexpat +except ImportError: + py.test.skip("No module expat") try: from pypy.module.pyexpat import interp_pyexpat Modified: pypy/branch/cpython-extension/pypy/module/pypyjit/interp_jit.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/pypyjit/interp_jit.py (original) +++ pypy/branch/cpython-extension/pypy/module/pypyjit/interp_jit.py Wed Mar 31 00:17:06 2010 @@ -78,13 +78,13 @@ except ExitFrame: return self.popvalue() - def JUMP_ABSOLUTE(f, jumpto, _, ec=None): + def jump_absolute(self, jumpto, _, ec=None): if we_are_jitted(): - f.last_instr = intmask(jumpto) - ec.bytecode_trace(f) - jumpto = r_uint(f.last_instr) - pypyjitdriver.can_enter_jit(frame=f, ec=ec, next_instr=jumpto, - pycode=f.getcode()) + self.last_instr = intmask(jumpto) + ec.bytecode_trace(self) + jumpto = r_uint(self.last_instr) + pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto, + pycode=self.getcode()) return jumpto Modified: pypy/branch/cpython-extension/pypy/module/rctime/interp_time.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/rctime/interp_time.py (original) +++ pypy/branch/cpython-extension/pypy/module/rctime/interp_time.py Wed Mar 31 00:17:06 2010 @@ -452,20 +452,18 @@ i = 1024 while True: - outbuf = lltype.malloc(rffi.CCHARP.TO, i + 1, flavor='raw') - buflen = c_strftime(outbuf, i, format, buf_value) - - if buflen > 0 or i >= 256 * len(format): - # if the buffer is 256 times as long as the format, - # it's probably not failing for lack of room! - # More likely, the format yields an empty result, - # e.g. an empty format, or %Z when the timezone - # is unknown. - if buflen < 0: buflen = 0 # should not occur - outbuf[buflen] = '\x00' - result = rffi.charp2str(outbuf) + outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw') + try: + buflen = c_strftime(outbuf, i, format, buf_value) + if buflen > 0 or i >= 256 * len(format): + # if the buffer is 256 times as long as the format, + # it's probably not failing for lack of room! + # More likely, the format yields an empty result, + # e.g. an empty format, or %Z when the timezone + # is unknown. + result = rffi.charp2strn(outbuf, buflen) + return space.wrap(result) + finally: lltype.free(outbuf, flavor='raw') - return space.wrap(result) - i += i strftime.unwrap_spec = [ObjSpace, str, W_Root] Modified: pypy/branch/cpython-extension/pypy/module/rctime/test/test_rctime.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/rctime/test/test_rctime.py (original) +++ pypy/branch/cpython-extension/pypy/module/rctime/test/test_rctime.py Wed Mar 31 00:17:06 2010 @@ -220,6 +220,14 @@ exp = '2000 01 01 00 00 00 1 001' assert rctime.strftime("%Y %m %d %H %M %S %w %j", (0,)*9) == exp + def test_strftime_ext(self): + import time as rctime + + tt = rctime.gmtime() + result = rctime.strftime('%D', tt) + if result != '': # else format not supported and we got '' + assert result == rctime.strftime('%m/%d/%y', tt) + def test_strftime_bounds_checking(self): import time as rctime Modified: pypy/branch/cpython-extension/pypy/module/readline/test/test_c_readline.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/readline/test/test_c_readline.py (original) +++ pypy/branch/cpython-extension/pypy/module/readline/test/test_c_readline.py Wed Mar 31 00:17:06 2010 @@ -2,8 +2,14 @@ Directly test the basic ctypes wrappers. """ +import py from pypy import conftest; conftest.translation_test_so_skip_if_appdirect() -from pypy.module.readline import c_readline +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) def test_basic_import(): Modified: pypy/branch/cpython-extension/pypy/module/readline/test/test_with_pypy.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/readline/test/test_with_pypy.py (original) +++ pypy/branch/cpython-extension/pypy/module/readline/test/test_with_pypy.py Wed Mar 31 00:17:06 2010 @@ -3,7 +3,14 @@ in the PyPy interpreter, itself running on top of CPython """ +import py from pypy.conftest import gettestobjspace +from pypy.rpython.tool import rffi_platform as platform + +try: + from pypy.module.readline import c_readline +except platform.CompilationError, e: + py.test.skip(e) class AppTestReadline: Modified: pypy/branch/cpython-extension/pypy/module/zipimport/interp_zipimport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/zipimport/interp_zipimport.py (original) +++ pypy/branch/cpython-extension/pypy/module/zipimport/interp_zipimport.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable, \ Arguments -from pypy.interpreter.error import OperationError, wrap_oserror, operationerrfmt +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.module import Module @@ -131,7 +131,7 @@ def _find_relative_path(self, filename): if filename.startswith(self.filename): filename = filename[len(self.filename):] - if filename.startswith(os.sep): + if filename.startswith(os.path.sep) or filename.startswith(ZIPSEP): filename = filename[1:] if ZIPSEP != os.path.sep: filename = filename.replace(os.path.sep, ZIPSEP) @@ -326,10 +326,12 @@ w_ZipImportError = space.getattr(space.getbuiltinmodule('zipimport'), w('ZipImportError')) ok = False - parts = name.split(os.path.sep) + parts_ends = [i for i in range(0, len(name)) + if name[i] == os.path.sep or name[i] == ZIPSEP] + parts_ends.append(len(name)) filename = "" # make annotator happy - for i in range(1, len(parts) + 1): - filename = os.path.sep.join(parts[:i]) + for i in parts_ends: + filename = name[:i] if not filename: filename = os.path.sep try: @@ -359,7 +361,7 @@ "%s seems not to be a zipfile", filename) zip_file.close() prefix = name[len(filename):] - if prefix.startswith(os.sep): + if prefix.startswith(os.path.sep) or prefix.startswith(ZIPSEP): prefix = prefix[1:] w_result = space.wrap(W_ZipImporter(space, name, filename, zip_file.NameToInfo, prefix)) Modified: pypy/branch/cpython-extension/pypy/module/zipimport/test/test_zipimport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/zipimport/test/test_zipimport.py (original) +++ pypy/branch/cpython-extension/pypy/module/zipimport/test/test_zipimport.py Wed Mar 31 00:17:06 2010 @@ -239,10 +239,11 @@ # value. Not sure why it doesn't the assertion uses import.archive # directly. -exarkun archive = importer.archive + realprefix = importer.prefix allbutlast = self.zipfile.split(os.path.sep)[:-1] prefix = 'directory' assert archive == self.zipfile - assert importer.prefix == prefix + assert realprefix == prefix def test_zip_directory_cache(self): """ Check full dictionary interface Modified: pypy/branch/cpython-extension/pypy/objspace/descroperation.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/descroperation.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/descroperation.py Wed Mar 31 00:17:06 2010 @@ -5,6 +5,7 @@ from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import default_identity_hash from pypy.tool.sourcetools import compile2, func_with_new_name +from pypy.module.__builtin__.interp_classobj import W_InstanceObject def object_getattribute(space): "Utility that returns the app-level descriptor object.__getattribute__." @@ -32,6 +33,17 @@ "'%s' object attribute '%s' is read-only", typename, name) +# Helpers for old-style and mix-style mixup + +def _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): + if (space.is_oldstyle_instance(w_obj1) and + space.is_oldstyle_instance(w_obj2)): + assert isinstance(w_obj1, W_InstanceObject) + assert isinstance(w_obj2, W_InstanceObject) + return space.is_w(w_obj1.w_class, w_obj2.w_class) + return space.is_w(w_typ1, w_typ2) + + class Object: def descr__getattribute__(space, w_obj, w_name): name = space.str_w(w_name) @@ -297,7 +309,7 @@ w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, '__pow__') - if space.is_w(w_typ1, w_typ2): + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, '__rpow__') @@ -581,7 +593,7 @@ w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) - if space.is_w(w_typ1, w_typ2): + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, right) @@ -604,8 +616,8 @@ # -- end of bug compatibility if space.is_true(space.issubtype(w_typ2, w_typ1)): if (w_left_src and w_right_src and - not space.abstract_issubclass_w(w_left_src, w_right_src) and - not space.abstract_issubclass_w(w_typ1, w_right_src)): + not space.abstract_issubclass_w(w_left_src, w_right_src) and + not space.abstract_issubclass_w(w_typ1, w_right_src)): w_obj1, w_obj2 = w_obj2, w_obj1 w_left_impl, w_right_impl = w_right_impl, w_left_impl @@ -632,8 +644,8 @@ w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) w_first = w_obj1 w_second = w_obj2 - - if space.is_w(w_typ1, w_typ2): + + if _same_class_w(space, w_obj1, w_obj2, w_typ1, w_typ2): w_right_impl = None else: w_right_src, w_right_impl = space.lookup_in_type_where(w_typ2, right) Modified: pypy/branch/cpython-extension/pypy/objspace/flow/model.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/flow/model.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/flow/model.py Wed Mar 31 00:17:06 2010 @@ -206,16 +206,10 @@ txt = "%s(%s)" % (txt, self.exitswitch) return txt - def reallyalloperations(self): - """Iterate over all operations, including cleanup sub-operations. - XXX remove!""" - for op in self.operations: - yield op - def getvariables(self): "Return all variables mentioned in this Block." result = self.inputargs[:] - for op in self.reallyalloperations(): + for op in self.operations: result += op.args result.append(op.result) return uniqueitems([w for w in result if isinstance(w, Variable)]) @@ -223,7 +217,7 @@ def getconstants(self): "Return all constants mentioned in this Block." result = self.inputargs[:] - for op in self.reallyalloperations(): + for op in self.operations: result += op.args return uniqueitems([w for w in result if isinstance(w, Constant)]) @@ -231,7 +225,7 @@ for a in mapping: assert isinstance(a, Variable), a self.inputargs = [mapping.get(a, a) for a in self.inputargs] - for op in self.reallyalloperations(): + for op in self.operations: op.args = [mapping.get(a, a) for a in op.args] op.result = mapping.get(op.result, op.result) self.exitswitch = mapping.get(self.exitswitch, self.exitswitch) Modified: pypy/branch/cpython-extension/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/flow/objspace.py Wed Mar 31 00:17:06 2010 @@ -8,6 +8,7 @@ from pypy.objspace.flow import flowcontext from pypy.objspace.flow.operation import FunctionByName from pypy.rlib.unroll import unrolling_iterable, _unroller +from pypy.rlib import rstackovf debug = 0 @@ -201,9 +202,13 @@ if not isinstance(check_class, tuple): # the simple case return ObjSpace.exception_match(self, w_exc_type, w_check_class) + # special case for StackOverflow (see rlib/rstackovf.py) + if check_class == rstackovf.StackOverflow: + w_real_class = self.wrap(rstackovf._StackOverflow) + return ObjSpace.exception_match(self, w_exc_type, w_real_class) # checking a tuple of classes for w_klass in self.fixedview(w_check_class): - if ObjSpace.exception_match(self, w_exc_type, w_klass): + if self.exception_match(w_exc_type, w_klass): return True return False @@ -230,9 +235,7 @@ if func.func_closure is None: closure = None else: - closure = [extract_cell_content(c, name, func) - for c, name in zip(func.func_closure, - func.func_code.co_freevars)] + closure = [extract_cell_content(c) for c in func.func_closure] # CallableFactory.pycall may add class_ to functions that are methods name = func.func_name class_ = getattr(func, 'class_', None) @@ -513,23 +516,17 @@ lis.append(OverflowError) implicit_exceptions[name+"_ovf"] = lis -#for _err in IndexError, KeyError: -# _add_exceptions("""getitem setitem delitem""", _err) for _name in 'getattr', 'delattr': _add_exceptions(_name, AttributeError) for _name in 'iter', 'coerce': _add_exceptions(_name, TypeError) -del _name#, _err +del _name _add_exceptions("""div mod divmod truediv floordiv pow inplace_div inplace_mod inplace_divmod inplace_truediv inplace_floordiv inplace_pow""", ZeroDivisionError) _add_exceptions("""pow inplace_pow lshift inplace_lshift rshift inplace_rshift""", ValueError) -##_add_exceptions("""add sub mul truediv floordiv div mod divmod pow -## inplace_add inplace_sub inplace_mul inplace_truediv -## inplace_floordiv inplace_div inplace_mod inplace_divmod -## inplace_pow""", FloatingPointError) _add_exceptions("""truediv divmod inplace_add inplace_sub inplace_mul inplace_truediv inplace_floordiv inplace_div inplace_mod inplace_pow @@ -540,25 +537,27 @@ OverflowError) # for the float case del _add_exceptions, _add_except_ovf -def extract_cell_content(c, varname='?', func='?'): +def extract_cell_content(c): """Get the value contained in a CPython 'cell', as read through the func_closure of a function object.""" - # yuk! this is all I could come up with that works in Python 2.2 too - class X(object): - def __cmp__(self, other): - self.other = other - return 0 - def __eq__(self, other): - self.other = other - return True - x = X() - x_cell, = (lambda: x).func_closure - x_cell == c try: - return x.other # crashes if the cell is actually empty + # This is simple on 2.5 + return getattr(c, "cell_contents") except AttributeError: - raise Exception("in %r, the free variable %r has no value" % ( - func, varname)) + class X(object): + def __cmp__(self, other): + self.other = other + return 0 + def __eq__(self, other): + self.other = other + return True + x = X() + x_cell, = (lambda: x).func_closure + x_cell == c + try: + return x.other # crashes if the cell is actually empty + except AttributeError: + raise ValueError("empty cell") def make_op(name, symbol, arity, specialnames): if hasattr(FlowObjSpace, name): Modified: pypy/branch/cpython-extension/pypy/objspace/std/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/__init__.py Wed Mar 31 00:17:06 2010 @@ -1,2 +1,2 @@ -from objspace import StdObjSpace +from pypy.objspace.std.objspace import StdObjSpace Space = StdObjSpace Modified: pypy/branch/cpython-extension/pypy/objspace/std/boolobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/boolobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/boolobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.intobject import W_IntObject Modified: pypy/branch/cpython-extension/pypy/objspace/std/booltype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/booltype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/booltype.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.inttype import int_typedef def descr__new__(space, w_booltype, w_obj=None): @@ -16,6 +17,6 @@ Returns True when the argument x is true, False otherwise. The builtins True and False are the only two instances of the class bool. The class bool is a subclass of the class int, and cannot be subclassed.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) bool_typedef.acceptable_as_base_class = False Modified: pypy/branch/cpython-extension/pypy/objspace/std/complexobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/complexobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/complexobject.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,7 @@ from pypy.interpreter import gateway -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.floatobject import W_FloatObject, _hash_float import math Modified: pypy/branch/cpython-extension/pypy/objspace/std/complextype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/complextype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/complextype.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,9 @@ -from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.strutil import interp_string_to_float, ParseStringError -from pypy.objspace.std.objspace import register_all from pypy.objspace.std.noneobject import W_NoneObject -from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef, newmethod +from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod # ERRORCODES @@ -36,7 +36,7 @@ # extract first number realstart = i pc = s[i] - while i < slen and s[i] != ' ': + while i < slen and s[i] != ' ': if s[i] in ('+','-') and pc not in ('e','E') and i != realstart: break pc = s[i] @@ -136,8 +136,9 @@ except ParseStringError: raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED)) else: - #check for overflow - if abs(realval) == OVERFLOWED_FLOAT or abs(imagval) == OVERFLOWED_FLOAT: + # check for overflow + if (abs(realval) == OVERFLOWED_FLOAT or + abs(imagval) == OVERFLOWED_FLOAT): raise OperationError(space.w_ValueError,space.wrap( "complex() literal too large to convert")) @@ -156,8 +157,8 @@ w_real = space.call_function(w_method) # __complex__() could return a string, which space.float() # could accept below... Let's catch this case. - if space.is_true(space.isinstance(w_imag, space.w_str)) or \ - space.is_true(space.isinstance(w_imag, space.w_unicode)): + if (space.is_true(space.isinstance(w_imag, space.w_str)) or + space.is_true(space.isinstance(w_imag, space.w_unicode))): raise OperationError(space.w_TypeError, space.wrap("__complex__() cannot return" " a string")) @@ -205,19 +206,19 @@ space.wrap("descriptor is for 'complex'")) return space.newfloat(getattr(w_obj, name)) return GetSetProperty(fget) - + def descr___getnewargs__(space, w_self): from pypy.objspace.std.complexobject import W_ComplexObject assert isinstance(w_self, W_ComplexObject) - return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) - + return space.newtuple([space.newcomplex(w_self.realval,w_self.imagval)]) + complex_typedef = StdTypeDef("complex", __doc__ = """complex(real[, imag]) -> complex number - + Create a complex number from a real part and an optional imaginary part. This is equivalent to (real + imag*1j) where imag defaults to 0.""", - __new__ = newmethod(descr__new__), - __getnewargs__ = newmethod(descr___getnewargs__), + __new__ = gateway.interp2app(descr__new__), + __getnewargs__ = gateway.interp2app(descr___getnewargs__), real = complexwprop('realval'), imag = complexwprop('imagval'), ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/default.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/default.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/default.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,7 @@ """Default implementation for some operation.""" -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all from pypy.rlib import objectmodel Modified: pypy/branch/cpython-extension/pypy/objspace/std/dictmultiobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/dictmultiobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/dictmultiobject.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,6 @@ import py, sys -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.argument import Signature Modified: pypy/branch/cpython-extension/pypy/objspace/std/dictproxyobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/dictproxyobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/dictproxyobject.py Wed Mar 31 00:17:06 2010 @@ -1,11 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all def descr_get_dictproxy(space, w_obj): return W_DictProxyObject(w_obj.getdict()) class W_DictProxyObject(W_Object): from pypy.objspace.std.dictproxytype import dictproxy_typedef as typedef - + def __init__(w_self, w_dict): w_self.w_dict = w_dict Modified: pypy/branch/cpython-extension/pypy/objspace/std/dictproxytype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/dictproxytype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/dictproxytype.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,7 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.interpreter.typedef import GetSetProperty from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cpython-extension/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/dicttype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/dicttype.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,8 @@ +from pypy.interpreter.baseobjspace import ObjSpace, W_Root +from pypy.interpreter.error import OperationError +from pypy.interpreter.mixedmodule import MixedModule from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -124,7 +127,6 @@ def itervalues(d): return iter(dict.values(d)) ''', filename=__file__) -#XXX what about dict.fromkeys()? dict_update__ANY = app.interphook("update") dict_popitem__ANY = app.interphook("popitem") @@ -138,6 +140,23 @@ register_all(vars(), globals()) + at gateway.unwrap_spec(ObjSpace, W_Root, W_Root, W_Root) +def descr_fromkeys(space, w_type, w_keys, w_fill=None): + if w_fill is None: + w_fill = space.w_None + w_dict = space.call_function(w_type) + w_iter = space.iter(w_keys) + while True: + try: + w_key = space.next(w_iter) + except OperationError, e: + if not e.match(space, space.w_StopIteration): + raise + break + space.setitem(w_dict, w_key, w_fill) + return w_dict + + # ____________________________________________________________ def descr__new__(space, w_dicttype, __args__): @@ -157,9 +176,12 @@ d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)''', - __new__ = newmethod(descr__new__, - unwrap_spec=[gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec= + [gateway.ObjSpace, + gateway.W_Root,gateway.Arguments]), __hash__ = no_hash_descr, + fromkeys = gateway.interp2app(descr_fromkeys, as_classmethod=True), ) dict_typedef.registermethods(globals()) @@ -180,18 +202,16 @@ XXX to do: remove this __reduce__ method and do a registration with copy_reg, instead. """ - from pypy.interpreter.mixedmodule import MixedModule w_mod = space.getbuiltinmodule('_pickle_support') mod = space.interp_w(MixedModule, w_mod) new_inst = mod.get('dictiter_surrogate_new') w_typeobj = space.gettypeobject(dictiter_typedef) - - from pypy.interpreter.mixedmodule import MixedModule + raise OperationError( space.w_RuntimeError, space.wrap("cannot pickle dictiters with multidicts")) # XXXXXX get that working again - + # we cannot call __init__ since we don't have the original dict if isinstance(w_self, W_DictIter_Keys): w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj) @@ -217,7 +237,7 @@ w_res ] w_ret = space.newtuple([new_inst, space.newtuple(tup)]) - return w_ret + return w_ret # ____________________________________________________________ Modified: pypy/branch/cpython-extension/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/floatobject.py Wed Mar 31 00:17:06 2010 @@ -1,15 +1,22 @@ -from pypy.objspace.std.objspace import * +import operator, new from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std import model +from pypy.objspace.std.multimethod import FailedToImplementArgs +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject from pypy.rlib.rarithmetic import ovfcheck_float_to_int, intmask, isinf, isnan -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT +from pypy.rlib.rbigint import rbigint +from pypy.tool.sourcetools import func_with_new_name import math from pypy.objspace.std.intobject import W_IntObject class W_FloatObject(W_Object): - """This is a reimplementation of the CPython "PyFloatObject" + """This is a reimplementation of the CPython "PyFloatObject" it is assumed that the constructor takes a real Python float as an argument""" from pypy.objspace.std.floattype import float_typedef as typedef @@ -88,82 +95,115 @@ s = formatd("%.12g", x) return space.wrap(should_not_look_like_an_int(s)) +# ____________________________________________________________ +# A mess to handle all cases of float comparison without relying +# on delegation, which can unfortunately loose precision when +# casting an int or a long to a float. + +def list_compare_funcs(declarator): + for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: + func, name = declarator(op) + globals()[name] = func_with_new_name(func, name) + +def _reverse(opname): + if opname[0] == 'l': return 'g' + opname[1:] + elif opname[0] == 'g': return 'l' + opname[1:] + else: return opname -def declare_new_float_comparison(opname): - import operator - from pypy.tool.sourcetools import func_with_new_name - op = getattr(operator, opname) - def f(space, w_int1, w_int2): - i = w_int1.floatval - j = w_int2.floatval - return space.newbool(op(i, j)) - name = opname + "__Float_Float" - return func_with_new_name(f, name), name - -for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']: - func, name = declare_new_float_comparison(op) - globals()[name] = func - -# for overflowing comparisons between longs and floats -# XXX we might have to worry (later) about eq__Float_Int, for the case -# where int->float conversion may lose precision :-( -def eq__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x) or math.floor(x) != x: - return space.w_False - try: - w_long1 = W_LongObject.fromfloat(x) - except OverflowError: - return space.w_False - return space.eq(w_long1, w_long2) - -def eq__Long_Float(space, w_long1, w_float2): - return eq__Float_Long(space, w_float2, w_long1) -def ne__Float_Long(space, w_float1, w_long2): - return space.not_(eq__Float_Long(space, w_float1, w_long2)) - -def ne__Long_Float(space, w_long1, w_float2): - return space.not_(eq__Float_Long(space, w_float2, w_long1)) - -def lt__Float_Long(space, w_float1, w_long2): - # XXX naive implementation - x = w_float1.floatval - if isinf(x): - return space.newbool(x < 0.0) - x_floor = math.floor(x) - try: - w_long1 = W_LongObject.fromfloat(x_floor) - except OverflowError: - return space.newbool(x < 0.0) - return space.lt(w_long1, w_long2) - -def lt__Long_Float(space, w_long1, w_float2): - return space.not_(le__Float_Long(space, w_float2, w_long1)) - -def le__Float_Long(space, w_float1, w_long2): - # XXX it's naive anyway - if space.is_true(space.lt(w_float1, w_long2)): - return space.w_True +def declare_compare_bigint(opname): + """Return a helper function that implements a float-bigint comparison.""" + op = getattr(operator, opname) + # + if opname == 'eq' or opname == 'ne': + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1) or math.floor(f1) != f1: + return opname == 'ne' + b1 = rbigint.fromfloat(f1) + res = b1.eq(b2) + if opname == 'ne': + res = not res + return res else: - return space.eq(w_float1, w_long2) + def do_compare_bigint(f1, b2): + """f1 is a float. b2 is a bigint.""" + if isinf(f1) or isnan(f1): + return op(f1, 0.0) + if opname == 'gt' or opname == 'le': + # 'float > long' <==> 'ceil(float) > long' + # 'float <= long' <==> 'ceil(float) <= long' + f1 = math.ceil(f1) + else: + # 'float < long' <==> 'floor(float) < long' + # 'float >= long' <==> 'floor(float) >= long' + f1 = math.floor(f1) + b1 = rbigint.fromfloat(f1) + return getattr(b1, opname)(b2) + # + return do_compare_bigint, 'compare_bigint_' + opname +list_compare_funcs(declare_compare_bigint) -def le__Long_Float(space, w_long1, w_float2): - return space.not_(lt__Float_Long(space, w_float2, w_long1)) -def gt__Float_Long(space, w_float1, w_long2): - return space.not_(le__Float_Long(space, w_float1, w_long2)) +def declare_cmp_float_float(opname): + op = getattr(operator, opname) + def f(space, w_float1, w_float2): + f1 = w_float1.floatval + f2 = w_float2.floatval + return space.newbool(op(f1, f2)) + return f, opname + "__Float_Float" +list_compare_funcs(declare_cmp_float_float) -def gt__Long_Float(space, w_long1, w_float2): - return lt__Float_Long(space, w_float2, w_long1) +def declare_cmp_float_int(opname): + op = getattr(operator, opname) + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_int2): + f1 = w_float1.floatval + i2 = w_int2.intval + f2 = float(i2) + if LONG_BIT > 32 and int(f2) != i2: + res = compare(f1, rbigint.fromint(i2)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Float_Int" +list_compare_funcs(declare_cmp_float_int) + +def declare_cmp_float_long(opname): + compare = globals()['compare_bigint_' + opname] + def f(space, w_float1, w_long2): + f1 = w_float1.floatval + b2 = w_long2.num + return space.newbool(compare(f1, b2)) + return f, opname + "__Float_Long" +list_compare_funcs(declare_cmp_float_long) -def ge__Float_Long(space, w_float1, w_long2): - return space.not_(lt__Float_Long(space, w_float1, w_long2)) +def declare_cmp_int_float(opname): + op = getattr(operator, opname) + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_int1, w_float2): + f2 = w_float2.floatval + i1 = w_int1.intval + f1 = float(i1) + if LONG_BIT > 32 and int(f1) != i1: + res = revcompare(f2, rbigint.fromint(i1)) + else: + res = op(f1, f2) + return space.newbool(res) + return f, opname + "__Int_Float" +list_compare_funcs(declare_cmp_int_float) + +def declare_cmp_long_float(opname): + revcompare = globals()['compare_bigint_' + _reverse(opname)] + def f(space, w_long1, w_float2): + f2 = w_float2.floatval + b1 = w_long1.num + return space.newbool(revcompare(f2, b1)) + return f, opname + "__Long_Float" +list_compare_funcs(declare_cmp_long_float) -def ge__Long_Float(space, w_long1, w_float2): - return le__Float_Long(space, w_float2, w_long1) +# ____________________________________________________________ def hash__Float(space, w_value): return space.wrap(_hash_float(space, w_value.floatval)) @@ -318,7 +358,20 @@ raise FailedToImplementArgs(space.w_OverflowError, space.wrap("float power")) except ValueError: - if x == 0.0 and y < 0.0: + # special case: "(-1.0) ** bignum" should not raise ValueError, + # unlike "math.pow(-1.0, bignum)". See http://mail.python.org/ + # - pipermail/python-bugs-list/2003-March/016795.html + if x < 0.0: + if math.floor(y) != y: + raise OperationError(space.w_ValueError, + space.wrap("negative number cannot be " + "raised to a fractional power")) + if x == -1.0: + if math.floor(y * 0.5) * 2.0 == y: + return space.wrap(1.0) + else: + return space.wrap( -1.0) + elif x == 0.0 and y < 0.0: raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 cannot be raised to a negative power")) raise OperationError(space.w_ValueError, @@ -349,11 +402,13 @@ w_float2 = delegate_Long2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, W_NoneObject, order=1) +model.MM.pow.register(pow_neg__Long_Long_None, W_LongObject, W_LongObject, + W_NoneObject, order=1) def pow_neg__Int_Int_None(space, w_int1, w_int2, thirdarg): w_float1 = delegate_Int2Float(space, w_int1) w_float2 = delegate_Int2Float(space, w_int2) return pow__Float_Float_ANY(space, w_float1, w_float2, thirdarg) -StdObjSpace.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=2) +model.MM.pow.register(pow_neg__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=2) Modified: pypy/branch/cpython-extension/pypy/objspace/std/floattype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/floattype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/floattype.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,6 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.objspace.std.strutil import string_to_float, ParseStringError from pypy.objspace.std.strutil import interp_string_to_float @@ -48,5 +49,5 @@ __doc__ = '''float(x) -> floating point number Convert a string or number to a floating point number, if possible.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/frozensettype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/frozensettype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/frozensettype.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,8 @@ -from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM + frozenset_copy = SMM('copy', 1, doc='Return a shallow copy of a set.') @@ -37,7 +36,8 @@ register_all(vars(), globals()) -def descr__frozenset__new__(space, w_frozensettype, w_iterable=NoneNotWrapped): +def descr__frozenset__new__(space, w_frozensettype, + w_iterable=gateway.NoneNotWrapped): from pypy.objspace.std.setobject import W_FrozensetObject from pypy.objspace.std.setobject import _is_frozenset_exact if (space.is_w(w_frozensettype, space.w_frozenset) and @@ -52,7 +52,7 @@ __doc__ = """frozenset(iterable) --> frozenset object Build an immutable unordered collection.""", - __new__ = newmethod(descr__frozenset__new__), + __new__ = gateway.interp2app(descr__frozenset__new__), ) frozenset_typedef.registermethods(globals()) Modified: pypy/branch/cpython-extension/pypy/objspace/std/intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/intobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/intobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,7 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/branch/cpython-extension/pypy/objspace/std/inttype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/inttype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/inttype.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_int, string_to_w_long, ParseStringError, ParseStringOverflowError +from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import (string_to_int, string_to_w_long, + ParseStringError, + ParseStringOverflowError) from pypy.rlib.rarithmetic import r_uint from pypy.rlib.objectmodel import instantiate @@ -47,8 +49,8 @@ except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) - -def descr__new__(space, w_inttype, w_x=0, w_base=NoneNotWrapped): + +def descr__new__(space, w_inttype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.intobject import W_IntObject w_longval = None w_value = w_x # 'x' is the keyword argument name in CPython @@ -64,7 +66,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) elif space.is_true(space.isinstance(w_value, space.w_unicode)): if space.config.objspace.std.withropeunicode: from pypy.objspace.std.ropeunicodeobject import unicode_to_decimal_w @@ -77,7 +79,7 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser) + w_longval = retry_to_w_long(space, e.parser) else: # otherwise, use the __int__() method w_obj = space.int(w_value) @@ -116,13 +118,13 @@ raise OperationError(space.w_ValueError, space.wrap(e.msg)) except ParseStringOverflowError, e: - w_longval = retry_to_w_long(space, e.parser, base) + w_longval = retry_to_w_long(space, e.parser, base) if w_longval is not None: if not space.is_w(w_inttype, space.w_int): raise OperationError(space.w_OverflowError, space.wrap( - "long int too large to convert to int")) + "long int too large to convert to int")) return w_longval elif space.is_w(w_inttype, space.w_int): # common case @@ -143,5 +145,5 @@ the optional base. It is an error to supply a base when converting a non-string. If the argument is outside the integer range a long object will be returned instead.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/iterobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/iterobject.py Wed Mar 31 00:17:06 2010 @@ -1,15 +1,12 @@ -""" -Reviewed 03-06-22 -Sequence-iteration is correctly implemented, thoroughly -tested, and complete. The only missing feature is support -for function-iteration. -""" -from pypy.objspace.std.objspace import * +"""Generic iterator implementations""" +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_AbstractSeqIterObject(W_Object): from pypy.objspace.std.itertype import iter_typedef as typedef - + def __init__(w_self, w_seq, index=0): if index < 0: index = 0 Modified: pypy/branch/cpython-extension/pypy/objspace/std/itertype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/itertype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/itertype.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cpython-extension/pypy/objspace/std/listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/listobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/listobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.objspace.std.inttype import wrapint Modified: pypy/branch/cpython-extension/pypy/objspace/std/listtype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/listtype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/listtype.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,6 @@ from pypy.interpreter import gateway from pypy.interpreter.error import OperationError -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from sys import maxint @@ -24,7 +24,8 @@ ' occurrences of value') list_reverse = SMM('reverse',1, doc='L.reverse() -- reverse *IN PLACE*') -list_sort = SMM('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse'], +list_sort = SMM('sort', 4, defaults=(None, None, False), + argnames=['cmp', 'key', 'reverse'], doc='L.sort(cmp=None, key=None, reverse=False) -- stable' ' sort *IN PLACE*;\ncmp(x, y) -> -1, 0, 1') list_reversed = SMM('__reversed__', 1, @@ -50,9 +51,9 @@ list_typedef = StdTypeDef("list", __doc__ = '''list() -> new list list(sequence) -> new list initialized from sequence's items''', - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) list_typedef.registermethods(globals()) Modified: pypy/branch/cpython-extension/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/longobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/longobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,9 @@ import sys -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std import model +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rbigint import rbigint, SHIFT @@ -120,11 +124,46 @@ def str__Long(space, w_long): return space.wrap(w_long.num.str()) -def eq__Long_Long(space, w_long1, w_long2): - return space.newbool(w_long1.num.eq(w_long2.num)) def lt__Long_Long(space, w_long1, w_long2): return space.newbool(w_long1.num.lt(w_long2.num)) +def le__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.le(w_long2.num)) +def eq__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.eq(w_long2.num)) +def ne__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ne(w_long2.num)) +def gt__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.gt(w_long2.num)) +def ge__Long_Long(space, w_long1, w_long2): + return space.newbool(w_long1.num.ge(w_long2.num)) + +def lt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.lt(rbigint.fromint(w_int2.intval))) +def le__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.le(rbigint.fromint(w_int2.intval))) +def eq__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.eq(rbigint.fromint(w_int2.intval))) +def ne__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ne(rbigint.fromint(w_int2.intval))) +def gt__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.gt(rbigint.fromint(w_int2.intval))) +def ge__Long_Int(space, w_long1, w_int2): + return space.newbool(w_long1.num.ge(rbigint.fromint(w_int2.intval))) + +def lt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).lt(w_long2.num)) +def le__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).le(w_long2.num)) +def eq__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).eq(w_long2.num)) +def ne__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ne(w_long2.num)) +def gt__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).gt(w_long2.num)) +def ge__Int_Long(space, w_int1, w_long2): + return space.newbool(rbigint.fromint(w_int1.intval).ge(w_long2.num)) + def hash__Long(space, w_value): return space.wrap(w_value.num.hash()) @@ -270,7 +309,8 @@ return %(opname)s__Long_Long(space, w_long1, w_long2) """ % {'opname': opname}, '', 'exec') - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], W_IntObject, W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], + W_IntObject, W_IntObject, order=1) # unary ops for opname in ['neg', 'abs']: @@ -280,7 +320,8 @@ return %(opname)s__Long(space, w_long1) """ % {'opname': opname} - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int' % opname], W_IntObject, order=1) + getattr(model.MM, opname).register(globals()['%s_ovr__Int' % opname], + W_IntObject, order=1) # pow def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3): @@ -293,7 +334,9 @@ w_long2 = delegate_Int2Long(space, w_int2) return pow__Long_Long_Long(space, w_long1, w_long2, w_long3) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=1) -StdObjSpace.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, W_LongObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, + W_NoneObject, order=1) +model.MM.pow.register(pow_ovr__Int_Int_Long, W_IntObject, W_IntObject, + W_LongObject, order=1) Modified: pypy/branch/cpython-extension/pypy/objspace/std/longtype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/longtype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/longtype.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,9 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.strutil import string_to_w_long, ParseStringError from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef +from pypy.objspace.std.strutil import string_to_w_long, ParseStringError -def descr__new__(space, w_longtype, w_x=0, w_base=NoneNotWrapped): +def descr__new__(space, w_longtype, w_x=0, w_base=gateway.NoneNotWrapped): from pypy.objspace.std.longobject import W_LongObject w_value = w_x # 'x' is the keyword argument name in CPython if w_base is None: @@ -75,5 +75,5 @@ string representation of a floating point number!) When converting a string, use the optional base. It is an error to supply a base when converting a non-string.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/marshal_impl.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/marshal_impl.py Wed Mar 31 00:17:06 2010 @@ -11,8 +11,8 @@ from pypy.interpreter.error import OperationError from pypy.objspace.std.register_all import register_all from pypy.rlib.rarithmetic import LONG_BIT +from pypy.objspace.std import longobject, model from pypy.objspace.std.longobject import SHIFT as long_bits -from pypy.objspace.std.objspace import StdObjSpace from pypy.interpreter.special import Ellipsis from pypy.interpreter.pycode import PyCode from pypy.interpreter import gateway, unicodehelper @@ -32,8 +32,6 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.unicodeobject import W_UnicodeObject -import longobject - from pypy.module.marshal.interp_marshal import register TYPE_NULL = '0' @@ -125,7 +123,7 @@ def marshal_w_Ellipsis(space, w_ellipsis, m): m.atom(TYPE_ELLIPSIS) -StdObjSpace.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) +model.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) def unmarshal_Ellipsis(space, u, tc): return space.w_Ellipsis @@ -399,7 +397,7 @@ m.put_int(x.co_firstlineno) m.atom_str(TYPE_STRING, x.co_lnotab) -StdObjSpace.MM.marshal_w.register(marshal_w_pycode, PyCode) +model.MM.marshal_w.register(marshal_w_pycode, PyCode) # helper for unmarshalling string lists of code objects. # unfortunately they now can be interned or referenced, Modified: pypy/branch/cpython-extension/pypy/objspace/std/model.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/model.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/model.py Wed Mar 31 00:17:06 2010 @@ -8,6 +8,12 @@ import pypy.interpreter.pycode import pypy.interpreter.special +_registered_implementations = set() +def registerimplementation(implcls): + """Hint to objspace.std.model to register the implementation class.""" + assert issubclass(implcls, W_Object) + _registered_implementations.add(implcls) + option_to_typename = { "withsmallint" : ["smallintobject.W_SmallIntObject"], "withstrslice" : ["strsliceobject.W_StringSliceObject"], @@ -132,8 +138,7 @@ if config.objspace.std.withrope: del self.typeorder[stringobject.W_StringObject] - #check if we missed implementations - from pypy.objspace.std.objspace import _registered_implementations + # check if we missed implementations for implcls in _registered_implementations: assert (implcls in self.typeorder or implcls in self.imported_but_not_registered), ( @@ -146,7 +151,7 @@ # register the order in which types are converted into each others # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - + if config.objspace.std.withsmallint: self.typeorder[boolobject.W_BoolObject] += [ (smallintobject.W_SmallIntObject, boolobject.delegate_Bool2SmallInt), @@ -171,11 +176,11 @@ ] self.typeorder[longobject.W_LongObject] += [ (floatobject.W_FloatObject, floatobject.delegate_Long2Float), - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Long2Complex), ] self.typeorder[floatobject.W_FloatObject] += [ - (complexobject.W_ComplexObject, + (complexobject.W_ComplexObject, complexobject.delegate_Float2Complex), ] self.typeorder[setobject.W_SetObject] += [ @@ -265,6 +270,60 @@ self._typeorder_with_empty_usersubcls = result return self._typeorder_with_empty_usersubcls +def _op_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_1, w_2)) + return op + +def _op_swapped(function): + def op(space, w_1, w_2): + return function(space, w_2, w_1) + return op + +def _op_swapped_negated(function): + def op(space, w_1, w_2): + return space.not_(function(space, w_2, w_1)) + return op + +OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] +OP_CORRESPONDANCES = [ + ('eq', 'ne', _op_negated), + ('lt', 'gt', _op_swapped), + ('le', 'ge', _op_swapped), + ('lt', 'ge', _op_negated), + ('le', 'gt', _op_negated), + ('lt', 'le', _op_swapped_negated), + ('gt', 'ge', _op_swapped_negated), + ] +for op1, op2, value in OP_CORRESPONDANCES[:]: + i = OP_CORRESPONDANCES.index((op1, op2, value)) + OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) + +def add_extra_comparisons(): + """ + Add the missing comparison operators if they were not explicitly + defined: eq <-> ne and lt <-> le <-> gt <-> ge. + We try to add them in the order defined by the OP_CORRESPONDANCES + table, thus favouring swapping the arguments over negating the result. + """ + originalentries = {} + for op in OPERATORS: + originalentries[op] = getattr(MM, op).signatures() + + for op1, op2, correspondance in OP_CORRESPONDANCES: + mirrorfunc = getattr(MM, op2) + for types in originalentries[op1]: + t1, t2 = types + if t1 is t2: + if not mirrorfunc.has_signature(types): + functions = getattr(MM, op1).getfunctions(types) + assert len(functions) == 1, ('Automatic' + ' registration of comparison functions' + ' only work when there is a single method for' + ' the operation.') + mirrorfunc.register(correspondance(functions[0]), *types) + + # ____________________________________________________________ W_ANY = W_Root @@ -276,11 +335,7 @@ __slots__ = () def __repr__(self): - s = '%s(%s)' % ( - self.__class__.__name__, - #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) - getattr(self, 'name', '') - ) + s = '%s(%s)' % (self.__class__.__name__, getattr(self, 'name', '')) w_cls = getattr(self, 'w__class__', None) if w_cls is not None and w_cls is not self: s += ' instance of %s' % self.w__class__ @@ -313,13 +368,13 @@ break else: self.name = operatorsymbol - + if extras.get('general__args__', False): self.argnames_after = ['__args__'] if extras.get('w_varargs', False): self.argnames_after = ['w_args'] if extras.get('varargs_w', False): - self.argnames_after = ['args_w'] + self.argnames_after = ['args_w'] self.argnames_after += extras.get('extra_args', []) def install_not_sliced(self, typeorder, baked_perform_call=True): @@ -352,3 +407,32 @@ # mm.dispatch_tree = merge(self.dispatch_tree, other.dispatch_tree) return mm + + +class MM: + """StdObjSpace multimethods""" + + call = StdObjSpaceMultiMethod('call', 1, ['__call__'], + general__args__=True) + init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) + getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) + # special visible multimethods + int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int + str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string + float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float + uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) + unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters + bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint + # NOTE: when adding more sometype_w() methods, you need to write a + # stub in default.py to raise a space.w_TypeError + marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) + + # add all regular multimethods here + for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: + if _name not in locals(): + mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) + locals()[_name] = mm + del mm + + pow.extras['defaults'] = (None,) Modified: pypy/branch/cpython-extension/pypy/objspace/std/noneobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/noneobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/noneobject.py Wed Mar 31 00:17:06 2010 @@ -2,9 +2,10 @@ None Object implementation ok and tested -""" +""" -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all class W_NoneObject(W_Object): from pypy.objspace.std.nonetype import none_typedef as typedef Modified: pypy/branch/cpython-extension/pypy/objspace/std/nonetype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/nonetype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/nonetype.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,4 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef # ____________________________________________________________ Modified: pypy/branch/cpython-extension/pypy/objspace/std/objectobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/objectobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/objectobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import W_Object, register_all +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all class W_ObjectObject(W_Object): Modified: pypy/branch/cpython-extension/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/objecttype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/objecttype.py Wed Mar 31 00:17:06 2010 @@ -1,10 +1,9 @@ from pypy.interpreter.error import OperationError, operationerrfmt -from pypy.objspace.descroperation import Object +from pypy.interpreter.typedef import GetSetProperty, default_identity_hash from pypy.interpreter import gateway -from pypy.interpreter.typedef import default_identity_hash -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.descroperation import Object +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr from pypy.objspace.std.register_all import register_all -from pypy.objspace.std.objspace import StdObjSpace def descr__repr__(space, w_obj): @@ -171,8 +170,8 @@ __repr__ = gateway.interp2app(descr__repr__), __class__ = GetSetProperty(descr__class__, descr_set___class__), __doc__ = '''The most base type''', - __new__ = newmethod(descr__new__, - unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, + unwrap_spec = [gateway.ObjSpace,gateway.W_Root,gateway.Arguments]), __hash__ = gateway.interp2app(default_identity_hash), __reduce_ex__ = gateway.interp2app(descr__reduce_ex__, unwrap_spec=[gateway.ObjSpace,gateway.W_Root,int]), Modified: pypy/branch/cpython-extension/pypy/objspace/std/objspace.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/objspace.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/objspace.py Wed Mar 31 00:17:06 2010 @@ -1,304 +1,76 @@ -from pypy.objspace.std.register_all import register_all +import __builtin__ +import types +from pypy.interpreter import pyframe, function, special from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, UnpackValueError -from pypy.interpreter.error import OperationError, operationerrfmt, debug_print +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter import pyframe -from pypy.interpreter import function -from pypy.interpreter.pyopcode import unrolling_compare_dispatch_table, \ - BytecodeCorruption +from pypy.objspace.std import (builtinshortcut, stdtypedef, frame, model, + transparent, callmethod, proxyobject) +from pypy.objspace.descroperation import DescrOperation, raiseattrerror from pypy.rlib.objectmodel import instantiate, r_dict from pypy.rlib.debug import make_sure_not_resized -from pypy.interpreter.gateway import PyPyCacheDir -from pypy.tool.cache import Cache -from pypy.tool.sourcetools import func_with_new_name -from pypy.objspace.std.model import W_Object, UnwrapError -from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel -from pypy.objspace.std.multimethod import FailedToImplement, FailedToImplementArgs -from pypy.objspace.descroperation import DescrOperation, raiseattrerror -from pypy.objspace.std import stdtypedef from pypy.rlib.rarithmetic import base_int from pypy.rlib.objectmodel import we_are_translated from pypy.rlib.jit import hint -from pypy.rlib.unroll import unrolling_iterable -import sys -import os -import __builtin__ - -_registered_implementations = {} -def registerimplementation(implcls): - # hint to objspace.std.model to register the implementation class - assert issubclass(implcls, W_Object) - _registered_implementations[implcls] = True - - -compare_table = [ - "lt", # "<" - "le", # "<=" - "eq", # "==" - "ne", # "!=" - "gt", # ">" - "ge", # ">=" - ] +from pypy.tool.sourcetools import func_with_new_name -unrolling_compare_ops = unrolling_iterable( - enumerate(compare_table)) +# Object imports +from pypy.objspace.std.boolobject import W_BoolObject +from pypy.objspace.std.complexobject import W_ComplexObject +from pypy.objspace.std.dictmultiobject import W_DictMultiObject +from pypy.objspace.std.floatobject import W_FloatObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.longobject import W_LongObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.ropeobject import W_RopeObject +from pypy.objspace.std.iterobject import W_SeqIterObject +from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject +from pypy.objspace.std.sliceobject import W_SliceObject +from pypy.objspace.std.smallintobject import W_SmallIntObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.typeobject import W_TypeObject + +# types +from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.stringtype import wrapstr +from pypy.objspace.std.unicodetype import wrapunicode -################################################################## class StdObjSpace(ObjSpace, DescrOperation): """The standard object space, implementing a general-purpose object library in Restricted Python.""" - PACKAGE_PATH = 'objspace.std' - def initialize(self): "NOT_RPYTHON: only for initializing the space." - self._typecache = Cache() - - # Import all the object types and implementations - self.model = StdTypeModel(self.config) - + # setup all the object types and implementations + self.model = model.StdTypeModel(self.config) - class StdObjSpaceFrame(pyframe.PyFrame): - if self.config.objspace.std.optimized_int_add: - if self.config.objspace.std.withsmallint: - def BINARY_ADD(f, oparg, *ignored): - from pypy.objspace.std.smallintobject import \ - W_SmallIntObject, add__SmallInt_SmallInt - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_SmallIntObject and type(w_2) is W_SmallIntObject: - try: - w_result = add__SmallInt_SmallInt(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - else: - def BINARY_ADD(f, oparg, *ignored): - from pypy.objspace.std.intobject import \ - W_IntObject, add__Int_Int - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_IntObject and type(w_2) is W_IntObject: - try: - w_result = add__Int_Int(f.space, w_1, w_2) - except FailedToImplement: - w_result = f.space.add(w_1, w_2) - else: - w_result = f.space.add(w_1, w_2) - f.pushvalue(w_result) - - if self.config.objspace.std.optimized_list_getitem: - def BINARY_SUBSCR(f, *ignored): - w_2 = f.popvalue() - w_1 = f.popvalue() - if type(w_1) is W_ListObject and type(w_2) is W_IntObject: - try: - w_result = w_1.wrappeditems[w_2.intval] - except IndexError: - raise OperationError(f.space.w_IndexError, - f.space.wrap("list index out of range")) - else: - w_result = f.space.getitem(w_1, w_2) - f.pushvalue(w_result) - - def LIST_APPEND(f, *ignored): - w = f.popvalue() - v = f.popvalue() - if type(v) is W_ListObject: - v.append(w) - else: - f.space.call_method(v, 'append', w) + self.FrameClass = frame.build_frame(self) - if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN: - def CALL_LIKELY_BUILTIN(f, oparg, *ignored): - from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module - from pypy.objspace.std.dictmultiobject import W_DictMultiObject - w_globals = f.w_globals - num = oparg >> 8 - assert isinstance(w_globals, W_DictMultiObject) - w_value = w_globals.get_builtin_indexed(num) - if w_value is None: - builtins = f.get_builtin() - assert isinstance(builtins, Module) - w_builtin_dict = builtins.w_dict - assert isinstance(w_builtin_dict, W_DictMultiObject) - w_value = w_builtin_dict.get_builtin_indexed(num) - ## if w_value is not None: - ## print "CALL_LIKELY_BUILTIN fast" - if w_value is None: - varname = OPTIMIZED_BUILTINS[num] - message = "global name '%s' is not defined" - raise operationerrfmt(f.space.w_NameError, - message, varname) - nargs = oparg & 0xff - w_function = w_value - try: - w_result = f.call_likely_builtin(w_function, nargs) - # XXX XXX fix the problem of resume points! - #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result) - finally: - f.dropvalues(nargs) - f.pushvalue(w_result) - - def call_likely_builtin(f, w_function, nargs): - if isinstance(w_function, function.Function): - executioncontext = self.getexecutioncontext() - executioncontext.c_call_trace(f, w_function) - res = w_function.funccall_valuestack(nargs, f) - executioncontext.c_return_trace(f, w_function) - return res - args = f.make_arguments(nargs) - return f.space.call_args(w_function, args) - - if self.config.objspace.opcodes.CALL_METHOD: - # def LOOKUP_METHOD(...): - from pypy.objspace.std.callmethod import LOOKUP_METHOD - # def CALL_METHOD(...): - from pypy.objspace.std.callmethod import CALL_METHOD - - if self.config.objspace.std.optimized_comparison_op: - def COMPARE_OP(f, testnum, *ignored): - import operator - w_2 = f.popvalue() - w_1 = f.popvalue() - w_result = None - if (type(w_2) is W_IntObject and type(w_1) is W_IntObject - and testnum < len(compare_table)): - for i, attr in unrolling_compare_ops: - if i == testnum: - op = getattr(operator, attr) - w_result = f.space.newbool(op(w_1.intval, - w_2.intval)) - break - else: - for i, attr in unrolling_compare_dispatch_table: - if i == testnum: - w_result = getattr(f, attr)(w_1, w_2) - break - else: - raise BytecodeCorruption, "bad COMPARE_OP oparg" - f.pushvalue(w_result) - - if self.config.objspace.std.logspaceoptypes: - _space_op_types = [] - for name, func in pyframe.PyFrame.__dict__.iteritems(): - if hasattr(func, 'binop'): - operationname = func.binop - def make_opimpl(operationname): - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_2 = f.popvalue() - w_1 = f.popvalue() - if we_are_translated(): - s = operationname + ' ' + str(w_1) + ' ' + str(w_2) - else: - s = operationname + ' ' + w_1.__class__.__name__ + ' ' + w_2.__class__.__name__ - f._space_op_types.append(s) - w_result = operation(w_1, w_2) - f.pushvalue(w_result) - return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) - locals()[name] = make_opimpl(operationname) - elif hasattr(func, 'unaryop'): - operationname = func.unaryop - def make_opimpl(operationname): - def opimpl(f, *ignored): - operation = getattr(f.space, operationname) - w_1 = f.popvalue() - if we_are_translated(): - s = operationname + ' ' + str(w_1) - else: - s = operationname + ' ' + w_1.__class__.__name__ - f._space_op_types.append(s) - w_result = operation(w_1) - f.pushvalue(w_result) - return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname) - locals()[name] = make_opimpl(operationname) - - self.FrameClass = StdObjSpaceFrame - - # store the dict class on the space to access it in various places - from pypy.objspace.std import dictmultiobject - self.DictObjectCls = dictmultiobject.W_DictMultiObject - - from pypy.objspace.std import tupleobject - self.TupleObjectCls = tupleobject.W_TupleObject - - if not self.config.objspace.std.withrope: - from pypy.objspace.std import stringobject - self.StringObjectCls = stringobject.W_StringObject - else: - from pypy.objspace.std import ropeobject - self.StringObjectCls = ropeobject.W_RopeObject - assert self.StringObjectCls in self.model.typeorder - - # install all the MultiMethods into the space instance - for name, mm in self.MM.__dict__.items(): - if not isinstance(mm, StdObjSpaceMultiMethod): - continue - if not hasattr(self, name): - if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object - func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) - else: - exprargs, expr, miniglobals, fallback = ( - mm.install_not_sliced(self.model.typeorder, baked_perform_call=False)) - - func = stdtypedef.make_perform_trampoline('__mm_'+name, - exprargs, expr, miniglobals, - mm) - - # e.g. add(space, w_x, w_y) - def make_boundmethod(func=func): - def boundmethod(*args): - return func(self, *args) - return func_with_new_name(boundmethod, 'boundmethod_'+name) - boundmethod = make_boundmethod() - setattr(self, name, boundmethod) # store into 'space' instance - elif self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut - if name.startswith('inplace_'): - fallback_name = name[len('inplace_'):] - if fallback_name in ('or', 'and'): - fallback_name += '_' - fallback_mm = self.MM.__dict__[fallback_name] - else: - fallback_mm = None - builtinshortcut.install(self, mm, fallback_mm) - - if self.config.objspace.std.builtinshortcut: - from pypy.objspace.std import builtinshortcut - builtinshortcut.install_is_true(self, self.MM.nonzero, self.MM.len) + if self.config.objspace.std.withrope: + self.StringObjectCls = W_RopeObject + else: + self.StringObjectCls = W_StringObject - # set up the method cache - if self.config.objspace.std.withmethodcache: - SIZE = 1 << self.config.objspace.std.methodcachesizeexp - self.method_cache_versions = [None] * SIZE - self.method_cache_names = [None] * SIZE - self.method_cache_lookup_where = [(None, None)] * SIZE - if self.config.objspace.std.withmethodcachecounter: - self.method_cache_hits = {} - self.method_cache_misses = {} - - # hack to avoid imports in the time-critical functions below - for cls in self.model.typeorder: - globals()[cls.__name__] = cls - for cls in self.model.imported_but_not_registered: - globals()[cls.__name__] = cls + self._install_multimethods() # singletons - self.w_None = W_NoneObject.w_None + self.w_None = W_NoneObject.w_None self.w_False = W_BoolObject.w_False - self.w_True = W_BoolObject.w_True - from pypy.interpreter.special import NotImplemented, Ellipsis - self.w_NotImplemented = self.wrap(NotImplemented(self)) - self.w_Ellipsis = self.wrap(Ellipsis(self)) + self.w_True = W_BoolObject.w_True + self.w_NotImplemented = self.wrap(special.NotImplemented(self)) + self.w_Ellipsis = self.wrap(special.Ellipsis(self)) # types + self.builtin_types = {} for typedef in self.model.pythontypes: w_type = self.gettypeobject(typedef) + self.builtin_types[typedef.name] = w_type setattr(self, 'w_' + typedef.name, w_type) + self.builtin_types["NotImplemented"] = self.w_NotImplemented + self.builtin_types["Ellipsis"] = self.w_Ellipsis # exceptions & builtins self.make_builtins() @@ -306,34 +78,48 @@ # the type of old-style classes self.w_classobj = self.builtin.get('__metaclass__') - # fix up a problem where multimethods apparently don't - # like to define this at interp-level - # HACK HACK HACK - from pypy.objspace.std.typeobject import _HEAPTYPE - old_flags = self.w_dict.__flags__ - self.w_dict.__flags__ |= _HEAPTYPE - self.appexec([self.w_dict], """ - (dict): - def fromkeys(cls, seq, value=None): - r = cls() - for s in seq: - r[s] = value - return r - dict.fromkeys = classmethod(fromkeys) - """) - self.w_dict.__flags__ = old_flags - # final setup self.setup_builtin_modules() # Adding transparent proxy call if self.config.objspace.std.withtproxy: - w___pypy__ = self.getbuiltinmodule("__pypy__") - from pypy.objspace.std.transparent import app_proxy, app_proxy_controller - - self.setattr(w___pypy__, self.wrap('tproxy'), - self.wrap(app_proxy)) - self.setattr(w___pypy__, self.wrap('get_tproxy_controller'), - self.wrap(app_proxy_controller)) + transparent.setup(self) + + def get_builtin_types(self): + return self.builtin_types + + def _install_multimethods(self): + """Install all the MultiMethods into the space instance.""" + model.add_extra_comparisons() + for name, mm in model.MM.__dict__.items(): + if not isinstance(mm, model.StdObjSpaceMultiMethod): + continue + if not hasattr(self, name): + # int_w, str_w...: these do not return a wrapped object + if name.endswith('_w'): + func = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=True) + else: + unsliced = mm.install_not_sliced(self.model.typeorder, + baked_perform_call=False) + exprargs, expr, miniglobals, fallback = unsliced + func = stdtypedef.make_perform_trampoline('__mm_'+name, + exprargs, expr, + miniglobals, mm) + + boundmethod = types.MethodType(func, self, self.__class__) + setattr(self, name, boundmethod) # store into 'space' instance + elif self.config.objspace.std.builtinshortcut: + if name.startswith('inplace_'): + fallback_name = name[len('inplace_'):] + if fallback_name in ('or', 'and'): + fallback_name += '_' + fallback_mm = model.MM.__dict__[fallback_name] + else: + fallback_mm = None + builtinshortcut.install(self, mm, fallback_mm) + if self.config.objspace.std.builtinshortcut: + builtinshortcut.install_is_true(self, model.MM.nonzero, + model.MM.len) def createexecutioncontext(self): # add space specific fields to execution context @@ -369,7 +155,7 @@ # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None - if isinstance(x, W_Object): + if isinstance(x, model.W_Object): raise TypeError, "attempt to wrap already wrapped object: %s"%(x,) if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% @@ -380,10 +166,8 @@ else: return self.newint(x) if isinstance(x, str): - from pypy.objspace.std.stringtype import wrapstr return wrapstr(self, x) if isinstance(x, unicode): - from pypy.objspace.std.unicodetype import wrapunicode return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) @@ -448,7 +232,6 @@ w_result = self.wrap_exception_cls(x) if w_result is not None: return w_result - #print "fake-wrapping", x from fake import fake_object return fake_object(self, x) @@ -457,23 +240,22 @@ def wrap_exception_cls(self, x): """NOT_RPYTHON""" if hasattr(self, 'w_' + x.__name__): - w_result = getattr(self, 'w_' + x.__name__) + w_result = getattr(self, 'w_' + x.__name__) return w_result return None wrap_exception_cls._annspecialcase_ = "override:wrap_exception_cls" - + def unwrap(self, w_obj): if isinstance(w_obj, Wrappable): return w_obj - if isinstance(w_obj, W_Object): + if isinstance(w_obj, model.W_Object): return w_obj.unwrap(self) - raise UnwrapError, "cannot unwrap: %r" % w_obj + raise model.UnwrapError, "cannot unwrap: %r" % w_obj def newint(self, intval): # this time-critical and circular-imports-funny method was stored # on 'self' by initialize() # not sure how bad this is: - from pypy.objspace.std.inttype import wrapint return wrapint(self, intval) def newfloat(self, floatval): @@ -486,18 +268,15 @@ return W_LongObject.fromint(self, val) def newtuple(self, list_w): - from pypy.objspace.std.tupletype import wraptuple assert isinstance(list_w, list) make_sure_not_resized(list_w) - return wraptuple(self, list_w) + return W_TupleObject(list_w) def newlist(self, list_w): - from pypy.objspace.std.listobject import W_ListObject return W_ListObject(list_w) def newdict(self, module=False, instance=False, classofinstance=None, from_strdict_shared=None, strdict=False): - from pypy.objspace.std.dictmultiobject import W_DictMultiObject return W_DictMultiObject.allocate_and_init_instance( self, module=module, instance=instance, classofinstance=classofinstance, @@ -675,21 +454,21 @@ def finditem_str(self, w_obj, key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem_str(key) return ObjSpace.finditem_str(self, w_obj, key) def finditem(self, w_obj, w_key): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): return w_obj.getitem(w_key) return ObjSpace.finditem(self, w_obj, w_key) def set_str_keyed_item(self, w_obj, key, w_value, shadows_type=True): # performance shortcut to avoid creating the OperationError(KeyError) - if (isinstance(w_obj, self.DictObjectCls) and + if (isinstance(w_obj, W_DictMultiObject) and not w_obj.user_overridden_class): w_obj.set_str_keyed_item(key, w_value, shadows_type) else: @@ -710,37 +489,10 @@ def call_method(self, w_obj, methname, *arg_w): if self.config.objspace.opcodes.CALL_METHOD: - from pypy.objspace.std.callmethod import call_method_opt - return call_method_opt(self, w_obj, methname, *arg_w) + return callmethod.call_method_opt(self, w_obj, methname, *arg_w) else: return ObjSpace.call_method(self, w_obj, methname, *arg_w) 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) - init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) - getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) - # special visible multimethods - int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int - str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string - float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float - uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) - unicode_w = StdObjSpaceMultiMethod('unicode_w', 1, []) # returns an unwrapped list of unicode characters - bigint_w = StdObjSpaceMultiMethod('bigint_w', 1, []) # returns an unwrapped rbigint - # NOTE: when adding more sometype_w() methods, you need to write a - # stub in default.py to raise a space.w_TypeError - marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) - log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) - - # add all regular multimethods here - for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: - if _name not in locals(): - mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) - locals()[_name] = mm - del mm - - pow.extras['defaults'] = (None,) Modified: pypy/branch/cpython-extension/pypy/objspace/std/proxyobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/proxyobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/proxyobject.py Wed Mar 31 00:17:06 2010 @@ -2,7 +2,7 @@ """ transparent list implementation """ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object from pypy.objspace.std.proxy_helpers import register_type from pypy.interpreter.error import OperationError from pypy.interpreter import baseobjspace, argument @@ -73,7 +73,7 @@ W_Transparent.__name__ = name return W_Transparent -W_Transparent = transparent_class('W_Transparent', Wrappable) +W_Transparent = transparent_class('W_Transparent', baseobjspace.Wrappable) W_TransparentObject = transparent_class('W_TransparentObject', W_Object) from pypy.objspace.std.objecttype import object_typedef Modified: pypy/branch/cpython-extension/pypy/objspace/std/rangeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/rangeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/rangeobject.py Wed Mar 31 00:17:06 2010 @@ -1,12 +1,12 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.inttype import wrapint 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 - -from pypy.objspace.std import slicetype +from pypy.objspace.std import listtype, iterobject, slicetype from pypy.interpreter import gateway, baseobjspace def length(start, stop, step): Modified: pypy/branch/cpython-extension/pypy/objspace/std/register_all.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/register_all.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/register_all.py Wed Mar 31 00:17:06 2010 @@ -1,60 +1,49 @@ +from pypy.objspace.std import model, stdtypedef _name_mappings = { 'and': 'and_', 'or': 'or_', } - + def register_all(module_dict, *alt_ns): - """register implementations for multimethods. + """register implementations for multimethods. By default a (name, object) pair of the given module dictionary is registered on the multimethod 'name' of StdObjSpace. If the name doesn't exist then the alternative namespace is tried - for registration. + for registration. """ - from pypy.objspace.std.objspace import StdObjSpace - from pypy.objspace.std.model import W_ANY, W_Object - from pypy.objspace.std.stdtypedef import StdTypeDef - namespaces = list(alt_ns) + [StdObjSpace.MM, StdObjSpace] + namespaces = list(alt_ns) + [model.MM] for name, obj in module_dict.items(): - if name.startswith('app_'): - print "%s: direct app definitions deprecated" % name + if name.startswith('app_'): + print "%s: direct app definitions deprecated" % name if name.find('__')<1 or name.startswith('app_'): continue funcname, sig = name.split('__') l=[] for i in sig.split('_'): if i == 'ANY': # just in case W_ANY is not in module_dict - icls = W_ANY + icls = model.W_ANY elif i == 'Object': # just in case W_Object is not in module_dict - icls = W_Object + icls = model.W_Object else: icls = (module_dict.get('W_%s' % i) or module_dict.get('W_%sObject' % i)) if icls is None: x = module_dict.get(i) - if isinstance(x, StdTypeDef): + if isinstance(x, stdtypedef.StdTypeDef): icls = x.any if icls is None: raise ValueError, \ "no W_%s or W_%sObject for the definition of %s" % ( i, i, name) l.append(icls) - - #XXX trying to be too clever at the moment for userobject.SpecialMethod - #if len(l) != obj.func_code.co_argcount-1: - # raise ValueError, \ - # "function name %s doesn't specify exactly %d arguments" % ( - # repr(name), obj.func_code.co_argcount-1) - funcname = _name_mappings.get(funcname, funcname) func = hack_func_by_name(funcname, namespaces) func.register(obj, *l) - add_extra_comparisons() - def hack_func_by_name(funcname, namespaces): for ns in namespaces: @@ -64,76 +53,5 @@ else: if hasattr(ns, funcname): return getattr(ns, funcname) - #import typetype - #try: - # return getattr(typetype.W_TypeType, funcname) - #except AttributeError: - # pass # catches not only the getattr() but the typetype.W_TypeType - # # in case it is not fully imported yet :-(((( - from pypy.objspace.std import objecttype - try: - return getattr(objecttype, funcname) - except AttributeError: - pass raise NameError, ("trying hard but not finding a multimethod named %s" % funcname) - - -def op_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_1, w_2)) - return op - -def op_swapped(function): - def op(space, w_1, w_2): - return function(space, w_2, w_1) - return op - -def op_swapped_negated(function): - def op(space, w_1, w_2): - return space.not_(function(space, w_2, w_1)) - return op - -OPERATORS = ['lt', 'le', 'eq', 'ne', 'gt', 'ge'] -OP_CORRESPONDANCES = [ - ('eq', 'ne', op_negated), - ('lt', 'gt', op_swapped), - ('le', 'ge', op_swapped), - ('lt', 'ge', op_negated), - ('le', 'gt', op_negated), - ('lt', 'le', op_swapped_negated), - ('gt', 'ge', op_swapped_negated), - ] -for op1, op2, value in OP_CORRESPONDANCES[:]: - i = OP_CORRESPONDANCES.index((op1, op2, value)) - OP_CORRESPONDANCES.insert(i+1, (op2, op1, value)) - -def add_extra_comparisons(): - """ - Add the missing comparison operators if they were not explicitly - defined: eq <-> ne and lt <-> le <-> gt <-> ge. - We try to add them in the order defined by the OP_CORRESPONDANCES - table, thus favouring swapping the arguments over negating the result. - """ - from pypy.objspace.std.objspace import StdObjSpace - originalentries = {} - for op in OPERATORS: - originalentries[op] = getattr(StdObjSpace.MM, op).signatures() - - for op1, op2, correspondance in OP_CORRESPONDANCES: - mirrorfunc = getattr(StdObjSpace.MM, op2) - for types in originalentries[op1]: - t1, t2 = types - if t1 is t2: - if not mirrorfunc.has_signature(types): - functions = getattr(StdObjSpace.MM, op1).getfunctions(types) - assert len(functions) == 1, ('Automatic' - ' registration of comparison functions' - ' only work when there is a single method for' - ' the operation.') - #print 'adding %s <<<%s>>> %s as %s(%s)' % ( - # t1, op2, t2, - # correspondance.func_name, functions[0].func_name) - mirrorfunc.register( - correspondance(functions[0]), - *types) Modified: pypy/branch/cpython-extension/pypy/objspace/std/ropeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/ropeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/ropeobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cpython-extension/pypy/objspace/std/ropeunicodeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/ropeunicodeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/ropeunicodeobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cpython-extension/pypy/objspace/std/setobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/setobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/setobject.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,8 @@ -from pypy.objspace.std.objspace import W_Object, OperationError -from pypy.objspace.std.objspace import registerimplementation, register_all +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.rlib.objectmodel import r_dict from pypy.rlib.rarithmetic import intmask, r_uint +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway from pypy.interpreter.argument import Signature from pypy.objspace.std.settype import set_typedef as settypedef Modified: pypy/branch/cpython-extension/pypy/objspace/std/settype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/settype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/settype.py Wed Mar 31 00:17:06 2010 @@ -1,8 +1,7 @@ from pypy.interpreter.error import OperationError -from pypy.objspace.std.objspace import register_all -from pypy.objspace.std.stdtypedef import StdTypeDef, newmethod, no_hash_descr -from pypy.objspace.std.stdtypedef import SMM -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.stdtypedef import StdTypeDef, no_hash_descr, SMM from pypy.interpreter import gateway set_add = SMM('add', 2, @@ -77,9 +76,9 @@ __doc__ = """set(iterable) --> set object Build an unordered collection.""", - __new__ = newmethod(descr__new__, unwrap_spec=[gateway.ObjSpace, - gateway.W_Root, - gateway.Arguments]), + __new__ = gateway.interp2app(descr__new__, unwrap_spec=[gateway.ObjSpace, + gateway.W_Root, + gateway.Arguments]), __hash__ = no_hash_descr, ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/sliceobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/sliceobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/sliceobject.py Wed Mar 31 00:17:06 2010 @@ -1,12 +1,9 @@ -""" -Reviewed 03-06-21 +"""Slice object""" -slice object construction tested, OK -indices method tested, OK -""" - -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError from pypy.interpreter import gateway +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.slicetype import _Eval_SliceIndex Modified: pypy/branch/cpython-extension/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/slicetype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/slicetype.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,6 @@ -import sys -from pypy.interpreter import baseobjspace -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import baseobjspace, gateway +from pypy.interpreter.typedef import GetSetProperty +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM, no_hash_descr from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError @@ -88,7 +88,7 @@ __doc__ = '''slice([start,] stop[, step]) Create a slice object. This is used for extended slicing (e.g. a[0:10:2]).''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __hash__ = no_hash_descr, start = slicewprop('w_start'), stop = slicewprop('w_stop'), Modified: pypy/branch/cpython-extension/pypy/objspace/std/smallintobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/smallintobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/smallintobject.py Wed Mar 31 00:17:06 2010 @@ -2,7 +2,10 @@ Implementation of small ints, stored as odd-valued pointers in the translated PyPy. To enable them, see inttype.py. """ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all +from pypy.objspace.std.multimethod import FailedToImplementArgs from pypy.objspace.std.noneobject import W_NoneObject from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint from pypy.objspace.std.inttype import wrapint Modified: pypy/branch/cpython-extension/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/stdtypedef.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/stdtypedef.py Wed Mar 31 00:17:06 2010 @@ -4,14 +4,13 @@ from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.typedef import no_hash_descr, descr_del_dict from pypy.interpreter.baseobjspace import SpaceCache +from pypy.objspace.std import model from pypy.objspace.std.model import StdObjSpaceMultiMethod from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib import jit from pypy.tool.sourcetools import compile2 -__all__ = ['StdTypeDef', 'newmethod', 'gateway', - 'GetSetProperty', 'Member', - 'SMM', 'descr_get_dict', 'no_hash_descr'] +__all__ = ['StdTypeDef', 'SMM', 'no_hash_descr'] SMM = StdObjSpaceMultiMethod @@ -42,11 +41,6 @@ std_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict) std_dict_descr.name = '__dict__' -def newmethod(descr_new, unwrap_spec=None): - "NOT_RPYTHON: initialization-time only." - # this is turned into a static method by the constructor of W_TypeObject. - return gateway.interp2app(descr_new, unwrap_spec=unwrap_spec) - # ____________________________________________________________ # # All the code below fishes from the multimethod registration tables @@ -288,8 +282,8 @@ def slicemultimethods(space, typedef): """NOT_RPYTHON""" result = {} - # import and slice all multimethods of the space.MM container - for multimethod in hack_out_multimethods(space.MM.__dict__): + # import and slice all multimethods of the MM container + for multimethod in hack_out_multimethods(model.MM.__dict__): slicemultimethod(space, multimethod, typedef, result) # import all multimethods defined directly on the type without slicing for multimethod in typedef.local_multimethods: @@ -301,9 +295,8 @@ multimethods that have an implementation whose first typed argument is 'cls'. """ - from pypy.objspace.std.objspace import StdObjSpace # XXX for now typedef = cls.typedef - for multimethod in hack_out_multimethods(StdObjSpace.MM.__dict__): + for multimethod in hack_out_multimethods(model.MM.__dict__): if cls in multimethod.dispatch_tree: yield multimethod, False for multimethod in typedef.local_multimethods: Modified: pypy/branch/cpython-extension/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/stringobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway Modified: pypy/branch/cpython-extension/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/stringtype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/stringtype.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.basestringtype import basestring_typedef from sys import maxint @@ -42,7 +43,7 @@ def sliced(space, s, start, stop, orig_obj): assert start >= 0 - assert stop >= 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 @@ -294,7 +295,7 @@ # ____________________________________________________________ str_typedef = StdTypeDef("str", basestring_typedef, - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __doc__ = '''str(object) -> string Return a nice string representation of the object. @@ -326,4 +327,3 @@ if u_self[start+i] != prefix[i]: return False return True - Modified: pypy/branch/cpython-extension/pypy/objspace/std/strjoinobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/strjoinobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/strjoinobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import * +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode Modified: pypy/branch/cpython-extension/pypy/objspace/std/strsliceobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/strsliceobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/strsliceobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,6 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std.unicodeobject import delegate_String2Unicode from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_complexobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_complexobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_complexobject.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,7 @@ import py from pypy.objspace.std import complexobject as cobj from pypy.objspace.std import complextype as cobjtype -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.std.stringobject import W_StringObject from pypy.objspace.std import StdObjSpace Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_dictmultiobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_dictmultiobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_dictmultiobject.py Wed Mar 31 00:17:06 2010 @@ -372,6 +372,12 @@ assert {}.fromkeys([]) == {} assert {1: 0, 2: 0, 3: 0}.fromkeys([1, '1'], 'j') == ( {1: 'j', '1': 'j'}) + class D(dict): + def __new__(cls): + return E() + class E(dict): + pass + assert isinstance(D.fromkeys([1, 2]), E) def test_str_uses_repr(self): class D(dict): Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_floatobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ from pypy.objspace.std import floatobject as fobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement import py class TestW_FloatObject: @@ -146,8 +146,7 @@ raises(ValueError, pw, -1.0, 0.5) assert pw(-1.0, 2.0) == 1.0 assert pw(-1.0, 3.0) == -1.0 - #assert pw(-1.0, 1e200) == 1.0 -- either 1.0, or ValueError, are - # -- acceptable answers IMHO + assert pw(-1.0, 1e200) == 1.0 def test_pow_neg_base(self): def pw(x, y): @@ -213,6 +212,8 @@ assert 13 <= 13.01 def test_comparison_more(self): + import sys + is_pypy = '__pypy__' in sys.builtin_module_names infinity = 1e200*1e200 nan = infinity/infinity for x in (123, 1 << 30, @@ -240,12 +241,27 @@ assert ((x + 1) > float(x)) assert not ((x + 1) < float(x)) # - #assert not (x == nan) - #assert not (x >= nan) - #assert not (x <= nan) - #assert (x != nan) - #assert not (x > nan) - #assert not (x < nan) + assert not (x == infinity) + assert not (x >= infinity) + assert (x <= infinity) + assert (x != infinity) + assert not (x > infinity) + assert (x < infinity) + # + assert not (x == -infinity) + assert (x >= -infinity) + assert not (x <= -infinity) + assert (x != -infinity) + assert (x > -infinity) + assert not (x < -infinity) + # + if is_pypy: + assert not (x == nan) + assert not (x >= nan) + assert not (x <= nan) + assert (x != nan) + assert not (x > nan) + assert not (x < nan) # assert (float(x) == x) assert (float(x) <= x) @@ -268,19 +284,35 @@ assert (float(x) < (x + 1)) assert not (float(x) > (x + 1)) # - #assert not (nan == x) - #assert not (nan <= x) - #assert not (nan >= x) - #assert (nan != x) - #assert not (nan < x) - #assert not (nan > x) + assert not (infinity == x) + assert (infinity >= x) + assert not (infinity <= x) + assert (infinity != x) + assert (infinity > x) + assert not (infinity < x) + # + assert not (-infinity == x) + assert not (-infinity >= x) + assert (-infinity <= x) + assert (-infinity != x) + assert not (-infinity > x) + assert (-infinity < x) + # + if is_pypy: + assert not (nan == x) + assert not (nan <= x) + assert not (nan >= x) + assert (nan != x) + assert not (nan < x) + assert not (nan > x) def test_multimethod_slice(self): assert 5 .__add__(3.14) is NotImplemented assert 3.25 .__add__(5) == 8.25 - if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent - assert 5 .__eq__(3.14) is NotImplemented - assert 3.14 .__eq__(5) is False + # xxx we are also a bit inconsistent about the following + #if hasattr(int, '__eq__'): # for py.test -A: CPython is inconsistent + # assert 5 .__eq__(3.14) is NotImplemented + # assert 3.14 .__eq__(5) is False #if hasattr(long, '__eq__'): # for py.test -A: CPython is inconsistent # assert 5L .__eq__(3.14) is NotImplemented # assert 3.14 .__eq__(5L) is False Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_intobject.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import intobject as iobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_listobject.py Wed Mar 31 00:17:06 2010 @@ -2,6 +2,7 @@ from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError +from pypy.conftest import gettestobjspace class TestW_ListObject: @@ -769,3 +770,18 @@ l = [1,2,3,4] l.__delslice__(0, 2) assert l == [3, 4] + + +class AppTestListFastSubscr: + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.optimized_list_getitem" : + True}) + + def test_getitem(self): + import operator + l = [0, 1, 2, 3, 4] + for i in xrange(5): + assert l[i] == i + assert l[3:] == [3, 4] + raises(TypeError, operator.getitem, l, "str") Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_longobject.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,7 @@ import py import sys from pypy.objspace.std import longobject as lobj -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter.error import OperationError from pypy.rlib.rarithmetic import r_uint from pypy.rlib.rbigint import rbigint @@ -60,37 +60,79 @@ assert a == 3L def test_compare(self): - BIG = 1L << 9999 - assert 0 == 0L - assert not (0 != 0L) - assert 0L == 0 - assert not (0L != 0) - assert not (0 == BIG) - assert 0 != BIG - assert not (BIG == 0) - assert BIG != 0 - assert not (0L == BIG) - assert 0L != BIG - assert 0 <= 0L - assert not (0 < 0L) - assert 0 <= BIG - assert 0 < BIG - assert not (BIG <= 0) - assert not (BIG < 0) - assert 0L <= 0L - assert not (0L < 0L) - assert 0L <= BIG - assert 0L < BIG - assert not (BIG <= 0L) - assert not (BIG < 0L) - assert not (0 <= -BIG) - assert not (0 < -BIG) - assert -BIG <= 0 - assert -BIG < 0 - assert not (0L <= -BIG) - assert not (0L < -BIG) - assert -BIG <= 0L - assert -BIG < 0L + for BIG in (1L, 1L << 62, 1L << 9999): + assert 0 == 0L + assert not (0 != 0L) + assert 0L == 0 + assert not (0L != 0) + assert not (0 == BIG) + assert 0 != BIG + assert not (BIG == 0) + assert BIG != 0 + assert not (0L == BIG) + assert 0L != BIG + assert 0 <= 0L + assert not (0 < 0L) + assert 0 <= BIG + assert 0 < BIG + assert not (BIG <= 0) + assert not (BIG < 0) + assert 0L <= 0L + assert not (0L < 0L) + assert 0L <= BIG + assert 0L < BIG + assert not (BIG <= 0L) + assert not (BIG < 0L) + assert not (0 <= -BIG) + assert not (0 < -BIG) + assert -BIG <= 0 + assert -BIG < 0 + assert not (0L <= -BIG) + assert not (0L < -BIG) + assert -BIG <= 0L + assert -BIG < 0L + # + assert not (BIG < int(BIG)) + assert (BIG <= int(BIG)) + assert (BIG == int(BIG)) + assert not (BIG != int(BIG)) + assert not (BIG > int(BIG)) + assert (BIG >= int(BIG)) + # + assert (BIG < int(BIG)+1) + assert (BIG <= int(BIG)+1) + assert not (BIG == int(BIG)+1) + assert (BIG != int(BIG)+1) + assert not (BIG > int(BIG)+1) + assert not (BIG >= int(BIG)+1) + # + assert not (BIG < int(BIG)-1) + assert not (BIG <= int(BIG)-1) + assert not (BIG == int(BIG)-1) + assert (BIG != int(BIG)-1) + assert (BIG > int(BIG)-1) + assert (BIG >= int(BIG)-1) + # + assert not (int(BIG) < BIG) + assert (int(BIG) <= BIG) + assert (int(BIG) == BIG) + assert not (int(BIG) != BIG) + assert not (int(BIG) > BIG) + assert (int(BIG) >= BIG) + # + assert not (int(BIG)+1 < BIG) + assert not (int(BIG)+1 <= BIG) + assert not (int(BIG)+1 == BIG) + assert (int(BIG)+1 != BIG) + assert (int(BIG)+1 > BIG) + assert (int(BIG)+1 >= BIG) + # + assert (int(BIG)-1 < BIG) + assert (int(BIG)-1 <= BIG) + assert not (int(BIG)-1 == BIG) + assert (int(BIG)-1 != BIG) + assert not (int(BIG)-1 > BIG) + assert not (int(BIG)-1 >= BIG) def test_conversion(self): class long2(long): Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_smallintobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_smallintobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_smallintobject.py Wed Mar 31 00:17:06 2010 @@ -5,9 +5,10 @@ # py.test.skip("WITHSMALLINT is not enabled") from pypy.objspace.std.inttype import wrapint -from pypy.objspace.std.objspace import FailedToImplement +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import r_uint +from pypy.objspace.std.test.test_intobject import AppTestInt from pypy.conftest import gettestobjspace class TestW_IntObject: @@ -223,3 +224,10 @@ f1 = wrapint(self.space, x) result = self.space.hex(f1) assert self.space.unwrap(result) == hex(x) + + +class AppTestSmallInt(AppTestInt): + + def setup_class(cls): + cls.space = gettestobjspace(**{"objspace.std.optimized_int_add" : True, + "objspace.std.withsmallint" : True}) Modified: pypy/branch/cpython-extension/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/test/test_typeobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import * -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.stdtypedef import StdTypeDef from pypy.conftest import gettestobjspace from pypy.objspace.std.typeobject import W_TypeObject @@ -15,7 +15,7 @@ def descr__new__(space, w_subtype): return space.allocate_instance(W_Stuff, w_subtype) W_Stuff.typedef = StdTypeDef("stuff", - __new__ = newmethod(descr__new__)) + __new__ = interp2app(descr__new__)) W_Stuff.typedef.acceptable_as_base_class = False w_stufftype = space.gettypeobject(W_Stuff.typedef) space.appexec([w_stufftype], """(stufftype): Modified: pypy/branch/cpython-extension/pypy/objspace/std/transparent.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/transparent.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/transparent.py Wed Mar 31 00:17:06 2010 @@ -20,6 +20,16 @@ type_cache = TypeCache() + +def setup(space): + """Add proxy functions to the __pypy__ module.""" + w___pypy__ = space.getbuiltinmodule("__pypy__") + space.setattr(w___pypy__, space.wrap('tproxy'), space.wrap(app_proxy)) + space.setattr(w___pypy__, space.wrap('get_tproxy_controller'), + space.wrap(app_proxy_controller)) + + + def proxy(space, w_type, w_controller): """tproxy(typ, controller) -> obj Return something that looks like it is of type typ. Its behaviour is Modified: pypy/branch/cpython-extension/pypy/objspace/std/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/tupleobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,8 @@ -from pypy.objspace.std.objspace import * +from pypy.interpreter.error import OperationError +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.inttype import wrapint +from pypy.objspace.std.multimethod import FailedToImplement from pypy.rlib.rarithmetic import intmask from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice from pypy.interpreter import gateway @@ -8,7 +11,7 @@ class W_TupleObject(W_Object): from pypy.objspace.std.tupletype import tuple_typedef as typedef _immutable_ = True - + def __init__(w_self, wrappeditems): make_sure_not_resized(wrappeditems) w_self.wrappeditems = wrappeditems # a list of wrapped values Modified: pypy/branch/cpython-extension/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/tupletype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/tupletype.py Wed Mar 31 00:17:06 2010 @@ -1,11 +1,7 @@ -from pypy.objspace.std.stdtypedef import * -from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter import gateway +from pypy.objspace.std.stdtypedef import StdTypeDef -def wraptuple(space, list_w): - from pypy.objspace.std.tupleobject import W_TupleObject - return W_TupleObject(list_w) - -def descr__new__(space, w_tupletype, w_sequence=NoneNotWrapped): +def descr__new__(space, w_tupletype, w_sequence=gateway.NoneNotWrapped): from pypy.objspace.std.tupleobject import W_TupleObject if w_sequence is None: tuple_w = [] @@ -14,8 +10,8 @@ return w_sequence else: tuple_w = space.fixedview(w_sequence) - w_obj = space.allocate_instance(space.TupleObjectCls, w_tupletype) - space.TupleObjectCls.__init__(w_obj, tuple_w) + w_obj = space.allocate_instance(W_TupleObject, w_tupletype) + W_TupleObject.__init__(w_obj, tuple_w) return w_obj # ____________________________________________________________ @@ -25,5 +21,5 @@ tuple(sequence) -> tuple initialized from sequence's items If the argument is a tuple, the return value is the same object.''', - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), ) Modified: pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/typeobject.py Wed Mar 31 00:17:06 2010 @@ -1,4 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object +from pypy.objspace.std.model import W_Object +from pypy.objspace.std.register_all import register_all from pypy.interpreter.function import Function, StaticMethod from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt @@ -47,6 +48,19 @@ class VersionTag(object): pass +class MethodCache(object): + + def __init__(self, space): + assert space.config.objspace.std.withmethodcache + SIZE = 1 << space.config.objspace.std.methodcachesizeexp + self.versions = [None] * SIZE + self.names = [None] * SIZE + self.lookup_where = [(None, None)] * SIZE + if space.config.objspace.std.withmethodcachecounter: + self.hits = {} + self.misses = {} + + class W_TypeObject(W_Object): from pypy.objspace.std.typetype import type_typedef as typedef @@ -265,7 +279,9 @@ @purefunction def _pure_lookup_where_with_method_cache(w_self, name, version_tag): space = w_self.space - SHIFT = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + cache = space.fromcache(MethodCache) + SHIFT2 = r_uint.BITS - space.config.objspace.std.methodcachesizeexp + SHIFT1 = SHIFT2 - 5 version_tag_as_int = current_object_addr_as_int(version_tag) # ^^^Note: if the version_tag object is moved by a moving GC, the # existing method cache entries won't be found any more; new @@ -274,24 +290,27 @@ # the time - so using the fast current_object_addr_as_int() instead # of a slower solution like hash() is still a good trade-off. hash_name = compute_hash(name) - method_hash = r_uint(intmask(version_tag_as_int * hash_name)) >> SHIFT - cached_version_tag = space.method_cache_versions[method_hash] + product = intmask(version_tag_as_int * hash_name) + method_hash = (r_uint(product) ^ (r_uint(product) << SHIFT1)) >> SHIFT2 + # ^^^Note2: we used to just take product>>SHIFT2, but on 64-bit + # platforms SHIFT2 is really large, and we loose too much information + # that way (as shown by failures of the tests that typically have + # method names like 'f' who hash to a number that has only ~33 bits). + cached_version_tag = cache.versions[method_hash] if cached_version_tag is version_tag: - cached_name = space.method_cache_names[method_hash] + cached_name = cache.names[method_hash] if cached_name is name: - tup = space.method_cache_lookup_where[method_hash] + tup = cache.lookup_where[method_hash] if space.config.objspace.std.withmethodcachecounter: - space.method_cache_hits[name] = \ - space.method_cache_hits.get(name, 0) + 1 + cache.hits[name] = cache.hits.get(name, 0) + 1 # print "hit", w_self, name return tup tup = w_self._lookup_where_all_typeobjects(name) - space.method_cache_versions[method_hash] = version_tag - space.method_cache_names[method_hash] = name - space.method_cache_lookup_where[method_hash] = tup + cache.versions[method_hash] = version_tag + cache.names[method_hash] = name + cache.lookup_where[method_hash] = tup if space.config.objspace.std.withmethodcachecounter: - space.method_cache_misses[name] = \ - space.method_cache_misses.get(name, 0) + 1 + cache.misses[name] = cache.misses.get(name, 0) + 1 # print "miss", w_self, name return tup Modified: pypy/branch/cpython-extension/pypy/objspace/std/typetype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/typetype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/typetype.py Wed Mar 31 00:17:06 2010 @@ -1,8 +1,9 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway from pypy.interpreter.argument import Arguments -from pypy.interpreter.typedef import weakref_descr -from pypy.objspace.std.stdtypedef import * +from pypy.interpreter.typedef import (GetSetProperty, descr_get_dict, + weakref_descr) +from pypy.objspace.std.stdtypedef import StdTypeDef def descr__new__(space, w_typetype, w_name, w_bases, w_dict): "This is used to create user-defined classes only." @@ -10,7 +11,7 @@ # XXX check types w_typetype = _precheck_for_new(space, w_typetype) - + bases_w = space.fixedview(w_bases) w_winner = w_typetype @@ -34,7 +35,7 @@ if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))): return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict) w_typetype = w_winner - + name = space.str_w(w_name) assert isinstance(name, str) dict_w = {} @@ -187,7 +188,7 @@ return space.get(w_result, space.w_None, w_type) def descr__flags(space, w_type): - w_type = _check(space, w_type) + w_type = _check(space, w_type) return space.wrap(w_type.__flags__) def descr_get__module(space, w_type): @@ -195,9 +196,9 @@ return w_type.get_module() def descr_set__module(space, w_type, w_value): - w_type = _check(space, w_type) + w_type = _check(space, w_type) if not w_type.is_heaptype(): - raise operationerrfmt(space.w_TypeError, + raise operationerrfmt(space.w_TypeError, "can't set %s.__module__", w_type.name) w_type.mutated() @@ -211,7 +212,7 @@ # ____________________________________________________________ type_typedef = StdTypeDef("type", - __new__ = newmethod(descr__new__), + __new__ = gateway.interp2app(descr__new__), __name__ = GetSetProperty(descr_get__name__, descr_set__name__), __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__), __base__ = GetSetProperty(descr__base), Modified: pypy/branch/cpython-extension/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/unicodeobject.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/unicodeobject.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.objspace.std.objspace import register_all, W_Object -from pypy.objspace.std.objspace import registerimplementation +from pypy.objspace.std.model import registerimplementation, W_Object +from pypy.objspace.std.register_all import register_all from pypy.objspace.std.multimethod import FailedToImplement from pypy.interpreter import gateway from pypy.interpreter.error import OperationError, operationerrfmt Modified: pypy/branch/cpython-extension/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/std/unicodetype.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/std/unicodetype.py Wed Mar 31 00:17:06 2010 @@ -1,8 +1,8 @@ +from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter import gateway -from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.stdtypedef import StdTypeDef, SMM from pypy.objspace.std.register_all import register_all from pypy.objspace.std.basestringtype import basestring_typedef -from pypy.interpreter.error import OperationError, operationerrfmt from sys import maxint @@ -286,7 +286,7 @@ # ____________________________________________________________ unicode_typedef = StdTypeDef("unicode", basestring_typedef, - __new__ = newmethod(descr_new_), + __new__ = gateway.interp2app(descr_new_), __doc__ = '''unicode(string [, encoding[, errors]]) -> object Create a new Unicode object from the given encoded string. Modified: pypy/branch/cpython-extension/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/branch/cpython-extension/pypy/objspace/test/test_descroperation.py (original) +++ pypy/branch/cpython-extension/pypy/objspace/test/test_descroperation.py Wed Mar 31 00:17:06 2010 @@ -22,82 +22,92 @@ cls.space = conftest.gettestobjspace(**cls.OPTIONS) def test_special_methods(self): - class A(object): - def __lt__(self, other): - return "lt" - def __imul__(self, other): - return "imul" - def __sub__(self, other): - return "sub" - def __rsub__(self, other): - return "rsub" - def __pow__(self, other): - return "pow" - def __rpow__(self, other): - return "rpow" - def __neg__(self): - return "neg" - a = A() - assert (a < 5) == "lt" - assert (object() > a) == "lt" - a1 = a - a1 *= 4 - assert a1 == "imul" - assert a - 2 == "sub" - assert a - object() == "sub" - assert 2 - a == "rsub" - assert object() - a == "rsub" - assert a ** 2 == "pow" - assert a ** object() == "pow" - assert 2 ** a == "rpow" - assert object() ** a == "rpow" - assert -a == "neg" - - class B(A): - def __lt__(self, other): - return "B's lt" - def __imul__(self, other): - return "B's imul" - def __sub__(self, other): - return "B's sub" - def __rsub__(self, other): - return "B's rsub" - def __pow__(self, other): - return "B's pow" - def __rpow__(self, other): - return "B's rpow" - def __neg__(self): - return "B's neg" - - b = B() - assert (a < b) == "lt" - assert (b > a) == "lt" - b1 = b - b1 *= a - assert b1 == "B's imul" - a1 = a - a1 *= b - assert a1 == "imul" - assert a - b == "B's rsub" - assert b - a == "B's sub" - assert b - b == "B's sub" - assert a ** b == "B's rpow" - assert b ** a == "B's pow" - assert b ** b == "B's pow" - assert -b == "B's neg" - - class C(B): + class OldStyle: pass - c = C() - assert c - 1 == "B's sub" - assert 1 - c == "B's rsub" - assert c - b == "B's sub" - assert b - c == "B's sub" - - assert c ** 1 == "B's pow" - assert 1 ** c == "B's rpow" - assert c ** b == "B's pow" - assert b ** c == "B's pow" + for base in (object, OldStyle,): + class A(base): + def __lt__(self, other): + return "lt" + def __imul__(self, other): + return "imul" + def __sub__(self, other): + return "sub" + def __rsub__(self, other): + return "rsub" + def __pow__(self, other): + return "pow" + def __rpow__(self, other): + return "rpow" + def __neg__(self): + return "neg" + a = A() + assert (a < 5) == "lt" + assert (object() > a) == "lt" + a1 = a + a1 *= 4 + assert a1 == "imul" + assert a - 2 == "sub" + assert a - object() == "sub" + assert 2 - a == "rsub" + assert object() - a == "rsub" + assert a ** 2 == "pow" + assert a ** object() == "pow" + assert 2 ** a == "rpow" + assert object() ** a == "rpow" + assert -a == "neg" + + class B(A): + def __lt__(self, other): + return "B's lt" + def __imul__(self, other): + return "B's imul" + def __sub__(self, other): + return "B's sub" + def __rsub__(self, other): + return "B's rsub" + def __pow__(self, other): + return "B's pow" + def __rpow__(self, other): + return "B's rpow" + def __neg__(self): + return "B's neg" + + b = B() + assert (a < b) == "lt" + assert (b > a) == "lt" + b1 = b + b1 *= a + assert b1 == "B's imul" + a1 = a + a1 *= b + assert a1 == "imul" + + if base is object: + assert a - b == "B's rsub" + else: + assert a - b == "sub" + assert b - a == "B's sub" + assert b - b == "B's sub" + if base is object: + assert a ** b == "B's rpow" + else: + assert a ** b == "pow" + assert b ** a == "B's pow" + assert b ** b == "B's pow" + assert -b == "B's neg" + + class C(B): + pass + c = C() + assert c - 1 == "B's sub" + assert 1 - c == "B's rsub" + assert c - b == "B's sub" + assert b - c == "B's sub" + + assert c ** 1 == "B's pow" + assert 1 ** c == "B's rpow" + assert c ** b == "B's pow" + assert b ** c == "B's pow" def test_getslice(self): class Sq(object): @@ -371,6 +381,74 @@ A() < B() assert l == [B, A, A, B] + def test_rich_comparison(self): + # Old-style + class A: + def __init__(self, a): + self.a = a + def __eq__(self, other): + return self.a == other.a + class B: + def __init__(self, a): + self.a = a + # New-style + class C(object): + def __init__(self, a): + self.a = a + def __eq__(self, other): + return self.a == other.a + class D(object): + def __init__(self, a): + self.a = a + + assert A(1) == B(1) + assert B(1) == A(1) + assert A(1) == C(1) + assert C(1) == A(1) + assert A(1) == D(1) + assert D(1) == A(1) + assert C(1) == D(1) + assert D(1) == C(1) + assert not(A(1) == B(2)) + assert not(B(1) == A(2)) + assert not(A(1) == C(2)) + assert not(C(1) == A(2)) + assert not(A(1) == D(2)) + assert not(D(1) == A(2)) + assert not(C(1) == D(2)) + assert not(D(1) == C(2)) + + def test_addition(self): + # Old-style + class A: + def __init__(self, a): + self.a = a + def __add__(self, other): + return self.a + other.a + __radd__ = __add__ + class B: + def __init__(self, a): + self.a = a + # New-style + class C(object): + def __init__(self, a): + self.a = a + def __add__(self, other): + return self.a + other.a + __radd__ = __add__ + class D(object): + def __init__(self, a): + self.a = a + + assert A(1) + B(2) == 3 + assert B(1) + A(2) == 3 + assert A(1) + C(2) == 3 + assert C(1) + A(2) == 3 + assert A(1) + D(2) == 3 + assert D(1) + A(2) == 3 + assert C(1) + D(2) == 3 + assert D(1) + C(2) == 3 + def test_mod_failure(self): try: [] % 3 Modified: pypy/branch/cpython-extension/pypy/rlib/_rsocket_rffi.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/_rsocket_rffi.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/_rsocket_rffi.py Wed Mar 31 00:17:06 2010 @@ -259,8 +259,8 @@ CConfig.sockaddr_in6 = platform.Struct('struct sockaddr_in6', [('sin6_family', rffi.INT), ('sin6_port', rffi.USHORT), - ('sin6_addr', CConfig.in6_addr), ('sin6_flowinfo', rffi.INT), + ('sin6_addr', CConfig.in6_addr), ('sin6_scope_id', rffi.INT)]) CConfig.sockaddr_un = platform.Struct('struct sockaddr_un', Modified: pypy/branch/cpython-extension/pypy/rlib/rarithmetic.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rarithmetic.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rarithmetic.py Wed Mar 31 00:17:06 2010 @@ -307,7 +307,7 @@ if val > klass.MASK>>1 or val < -(klass.MASK>>1)-1: raise OverflowError("%s does not fit in signed %d-bit integer"%(val, klass.BITS)) if val < 0: - val = - ((-val) & klass.MASK) + val = ~ ((~val) & klass.MASK) return super(signed_int, klass).__new__(klass, val) typemap = {} Modified: pypy/branch/cpython-extension/pypy/rlib/rbigint.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rbigint.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rbigint.py Wed Mar 31 00:17:06 2010 @@ -49,6 +49,7 @@ class rbigint(object): """This is a reimplementation of longs using a list of digits.""" + # XXX relace the list of ints with a list of rffi.INTs, maybe def __init__(self, digits=None, sign=0): if digits is None or len(digits) == 0: @@ -272,13 +273,13 @@ return False def le(self, other): - return self.lt(other) or self.eq(other) + return not other.lt(self) def gt(self, other): - return other.le(self) + return other.lt(self) def ge(self, other): - return other.lt(self) + return not self.lt(other) def hash(self): return _hash(self) Modified: pypy/branch/cpython-extension/pypy/rlib/rmarshal.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rmarshal.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rmarshal.py Wed Mar 31 00:17:06 2010 @@ -6,7 +6,7 @@ from pypy.annotation.signature import annotation from pypy.annotation.listdef import ListDef, TooLateForChange from pypy.tool.pairtype import pair, pairtype -from pypy.rlib.rarithmetic import formatd, r_longlong, intmask +from pypy.rlib.rarithmetic import formatd, r_longlong, intmask, LONG_BIT from pypy.rlib.rarithmetic import break_up_float, parts_to_float from pypy.rlib.unroll import unrolling_iterable @@ -151,8 +151,12 @@ add_loader(annmodel.s_Bool, load_bool) def dump_int(buf, x): - buf.append(TYPE_INT) - w_long(buf, x) + # only use TYPE_INT on 32-bit platforms + if LONG_BIT > 32: + dump_longlong(buf, r_longlong(x)) + else: + buf.append(TYPE_INT) + w_long(buf, x) add_dumper(annmodel.SomeInteger(), dump_int) def load_int_nonneg(loader): @@ -163,9 +167,14 @@ add_loader(annmodel.SomeInteger(nonneg=True), load_int_nonneg) def load_int(loader): - if readchr(loader) != TYPE_INT: - raise ValueError("expected an int") - return readlong(loader) + r = readchr(loader) + if LONG_BIT > 32 and r == TYPE_INT64: + x = readlong(loader) & 0xFFFFFFFF + x |= readlong(loader) << 32 + return x + if r == TYPE_INT: + return readlong(loader) + raise ValueError("expected an int") add_loader(annmodel.SomeInteger(), load_int) def dump_longlong(buf, x): Modified: pypy/branch/cpython-extension/pypy/rlib/rsocket.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rsocket.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rsocket.py Wed Mar 31 00:17:06 2010 @@ -42,13 +42,15 @@ return rffi.cast(lltype.Signed, _c.ntohs(x)) def ntohl(x): - return rffi.cast(lltype.Signed, _c.ntohl(x)) + # accepts and returns an Unsigned + return rffi.cast(lltype.Unsigned, _c.ntohl(x)) def htons(x): return rffi.cast(lltype.Signed, _c.htons(x)) def htonl(x): - return rffi.cast(lltype.Signed, _c.htonl(x)) + # accepts and returns an Unsigned + return rffi.cast(lltype.Unsigned, _c.htonl(x)) _FAMILIES = {} @@ -504,6 +506,10 @@ klass = familyclass(family) result = instantiate(klass) buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor='raw', zero=True) + # Initialize the family to the correct value. Avoids surprizes on + # Windows when calling a function that unexpectedly does not set + # the output address (e.g. recvfrom() on a connected IPv4 socket). + rffi.setintfield(rffi.cast(_c.sockaddr_ptr, buf), 'c_sa_family', family) result.setdata(buf, 0) return result, klass.maxlen Modified: pypy/branch/cpython-extension/pypy/rlib/rstack.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rstack.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rstack.py Wed Mar 31 00:17:06 2010 @@ -38,8 +38,9 @@ stack_too_big = rffi.llexternal('LL_stack_too_big', [], rffi.INT, compilation_info=compilation_info, _nowrapper=True, - _callable=lambda: 0, + _callable=lambda: _zero, sandboxsafe=True) +_zero = rffi.cast(rffi.INT, 0) def stack_check(): if rffi.cast(lltype.Signed, stack_too_big()): Modified: pypy/branch/cpython-extension/pypy/rlib/rzipfile.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/rzipfile.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/rzipfile.py Wed Mar 31 00:17:06 2010 @@ -217,7 +217,7 @@ + fheader[_FH_EXTRA_FIELD_LENGTH]) fname = fp.read(fheader[_FH_FILENAME_LENGTH]) if fname != data.orig_filename: - raise RuntimeError, \ + raise BadZipfile, \ 'File name in directory "%s" and header "%s" differ.' % ( data.orig_filename, fname) fp.seek(self.start_dir, 0) Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rarithmetic.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rarithmetic.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rarithmetic.py Wed Mar 31 00:17:06 2010 @@ -197,6 +197,10 @@ x = intmask(tp(5)) assert (type(x), x) == (int, 5) +def test_bug_creating_r_int(): + minint = -sys.maxint-1 + assert r_int(r_int(minint)) == minint + def test_ovfcheck(): one = 1 x = sys.maxint Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rbigint.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rbigint.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rbigint.py Wed Mar 31 00:17:06 2010 @@ -106,7 +106,7 @@ assert rbigint.fromrarith_int(r_uint(17)).eq(rbigint([17], 1)) assert rbigint.fromrarith_int(r_uint(BASE-1)).eq(rbigint([intmask(BASE-1)], 1)) assert rbigint.fromrarith_int(r_uint(BASE)).eq(rbigint([0, 1], 1)) - assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) + #assert rbigint.fromrarith_int(r_uint(BASE**2)).eq(rbigint([0], 0)) assert rbigint.fromrarith_int(r_uint(sys.maxint)).eq( rbigint.fromint(sys.maxint)) assert rbigint.fromrarith_int(r_uint(sys.maxint+1)).eq( @@ -193,6 +193,14 @@ f2 = rbigint.fromlong(y) assert (x < y) == f1.lt(f2) + def test_order(self): + f6 = rbigint.fromint(6) + f7 = rbigint.fromint(7) + assert (f6.lt(f6), f6.lt(f7), f7.lt(f6)) == (0,1,0) + assert (f6.le(f6), f6.le(f7), f7.le(f6)) == (1,1,0) + assert (f6.gt(f6), f6.gt(f7), f7.gt(f6)) == (0,0,1) + assert (f6.ge(f6), f6.ge(f7), f7.ge(f6)) == (1,0,1) + def test_int_conversion(self): f1 = rbigint.fromlong(12332) f2 = rbigint.fromint(12332) @@ -465,9 +473,12 @@ def test_args_from_rarith_int(self): from pypy.rpython.tool.rfficache import platform + from pypy.rlib.rarithmetic import r_int classlist = platform.numbertype_to_rclass.values() fnlist = [] for r in classlist: + if r is r_int: # and also r_longlong on 64-bit + continue if r is int: mask = sys.maxint*2+1 signed = True Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rmarshal.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rmarshal.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rmarshal.py Wed Mar 31 00:17:06 2010 @@ -2,7 +2,7 @@ import marshal from pypy.rlib.rmarshal import * from pypy.annotation import model as annmodel -from pypy.rlib.rarithmetic import formatd +from pypy.rlib.rarithmetic import formatd, LONG_BIT types_that_can_be_none = [ [int], @@ -17,6 +17,10 @@ assert marshal.loads(''.join(buf)) == 5 buf = [] + get_marshaller(int)(buf, -555) + assert marshal.loads(''.join(buf)) == -555 + + buf = [] get_marshaller(float)(buf, 3.25) assert marshal.loads(''.join(buf)) == 3.25 @@ -37,6 +41,15 @@ assert marshal.loads(''.join(buf)) == 0x12380000007 buf = [] + get_marshaller(r_longlong)(buf, r_longlong(-0x12380000007)) + assert marshal.loads(''.join(buf)) == -0x12380000007 + + if LONG_BIT > 32: + buf = [] + get_marshaller(int)(buf, -0x12340000007) + assert marshal.loads(''.join(buf)) == -0x12340000007 + + buf = [] get_marshaller([int])(buf, [2, 5, -7]) assert marshal.loads(''.join(buf)) == [2, 5, -7] @@ -54,6 +67,9 @@ buf = 'i\x05\x00\x00\x00' assert get_unmarshaller(int)(buf) == 5 + buf = 'i\x00\xf0\xff\xff' + assert get_unmarshaller(int)(buf) == -4096 + buf = 'f\x043.25' assert get_unmarshaller(float)(buf) == 3.25 @@ -75,6 +91,16 @@ buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' assert get_unmarshaller(r_longlong)(buf) == 0x12380000007 + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(r_longlong)(buf) == -7566046822028738560L + + if LONG_BIT > 32: + buf = 'I\x07\x00\x00\x80\x23\x01\x00\x00' + assert get_unmarshaller(int)(buf) == 0x12380000007 + + buf = 'I\x00\x00\x01\x83\x80\x00\x00\x97' + assert get_unmarshaller(int)(buf) == -7566046822028738560 + buf = ('[\x03\x00\x00\x00i\x02\x00\x00\x00i\x05\x00\x00\x00' 'i\xf9\xff\xff\xff') assert get_unmarshaller([int])(buf) == [2, 5, -7] @@ -98,10 +124,18 @@ return ''.join(buf) res = interpret(f, []) res = ''.join(res.chars) - assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' - 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' - 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' - 'f\x061e+100') + if LONG_BIT == 32: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00i\x05\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'i\x07\x00\x00\x00s\x05\x00\x00\x00world' + 'f\x061e+100') + else: + assert res == ('[\x02\x00\x00\x00(\x03\x00\x00\x00' + 'I\x05\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00hellof\x04-0.5(\x03\x00\x00\x00' + 'I\x07\x00\x00\x00\x00\x00\x00\x00' + 's\x05\x00\x00\x00world' + 'f\x061e+100') def test_llinterp_unmarshal(): from pypy.rpython.test.test_llinterp import interpret Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rsocket.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rsocket.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rsocket.py Wed Mar 31 00:17:06 2010 @@ -78,6 +78,19 @@ py.test.fail("could not find the 127.0.0.1 IPv4 address in %r" % (address_list,)) + name, aliases, address_list = gethostbyaddr('localhost') + allnames = [name] + aliases + for n in allnames: + assert isinstance(n, str) + if sys.platform != 'win32': + assert 'localhost' in allnames + for a in address_list: + if isinstance(a, INET6Address) and a.get_host() == "::1": + break # ok + else: + py.test.fail("could not find the ::1 IPv6 address in %r" + % (address_list,)) + def test_getservbyname(): assert getservbyname('http') == 80 assert getservbyname('http', 'tcp') == 80 Modified: pypy/branch/cpython-extension/pypy/rlib/test/test_rstruct.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/test/test_rstruct.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/test/test_rstruct.py Wed Mar 31 00:17:06 2010 @@ -1,12 +1,14 @@ from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.rstruct.runpack import runpack +from pypy.rlib.rarithmetic import LONG_BIT import struct class BaseTestRStruct(BaseRtypingTest): def test_unpack(self): + pad = '\x00' * (LONG_BIT//8-1) # 3 or 7 null bytes def fn(): - return runpack('sll', 'a\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00')[1] + return runpack('sll', 'a'+pad+'\x03'+pad+'\x04'+pad)[1] assert fn() == 3 assert self.interpret(fn, []) == 3 Modified: pypy/branch/cpython-extension/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/exceptiondata.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/exceptiondata.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,6 @@ from pypy.rpython import rclass from pypy.annotation import model as annmodel +from pypy.rlib import rstackovf # the exceptions that can be implicitely raised by some operations @@ -19,6 +20,7 @@ UnicodeDecodeError: True, UnicodeEncodeError: True, NotImplementedError: True, + rstackovf._StackOverflow: True, } Modified: pypy/branch/cpython-extension/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/llinterp.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/llinterp.py Wed Mar 31 00:17:06 2010 @@ -5,6 +5,7 @@ from pypy.rpython.lltypesystem import rclass from pypy.rpython.ootypesystem import ootype from pypy.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic +from pypy.rlib import rstackovf import sys, os import math @@ -321,6 +322,18 @@ except LLException, e: if not (catch_exception and op is block.operations[-1]): raise + except RuntimeError, e: + rstackovf.check_stack_overflow() + # xxx fish fish fish for proper etype and evalue to use + rtyper = self.llinterpreter.typer + bk = rtyper.annotator.bookkeeper + classdef = bk.getuniqueclassdef(rstackovf._StackOverflow) + exdata = rtyper.getexceptiondata() + evalue = exdata.get_standard_ll_exc_instance(rtyper, classdef) + etype = exdata.fn_type_of_exc_inst(evalue) + e = LLException(etype, evalue) + if not (catch_exception and op is block.operations[-1]): + raise e # determine nextblock and/or return value if len(block.exits) == 0: Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/llgroup.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/llgroup.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/llgroup.py Wed Mar 31 00:17:06 2010 @@ -50,9 +50,11 @@ if LONG_BIT == 32: + HALFSHIFT = 16 HALFWORD = rffi.USHORT r_halfword = rffi.r_ushort else: + HALFSHIFT = 32 HALFWORD = rffi.UINT r_halfword = rffi.r_uint @@ -97,7 +99,7 @@ '&~0xFFFF' or with a direct masking like '&0x10000' (resp. on 64-bit platform, with '&~0xFFFFFFFF' or '&0x100000000'). """ - MASK = (1<<(LONG_BIT//2))-1 # 0xFFFF or 0xFFFFFFFF + MASK = (1<> 31)) * float(0x80000000) @@ -290,7 +297,7 @@ small = f / r high = int(small) truncated = int((small - high) * r) - return r_longlong(high) * 0x100000000 + truncated + return r_longlong_result(high) * 0x100000000 + truncated def op_cast_char_to_int(b): assert type(b) is str and len(b) == 1 @@ -314,10 +321,10 @@ def op_cast_int_to_longlong(b): assert type(b) is int - return r_longlong(b) + return r_longlong_result(b) def op_truncate_longlong_to_int(b): - assert type(b) is r_longlong + assert isinstance(b, r_longlong_arg) return intmask(b) def op_cast_pointer(RESTYPE, obj): Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/rffi.py Wed Mar 31 00:17:06 2010 @@ -356,10 +356,9 @@ MODE_T = lltype.Signed PID_T = lltype.Signed -def setup(): - """ creates necessary c-level types - """ - result = [] +def populate_inttypes(): + names = [] + populatelist = [] for name in TYPES: c_name = name if name.startswith('unsigned'): @@ -368,7 +367,18 @@ else: signed = (name != 'size_t') name = name.replace(' ', '') - tp = platform.inttype(name.upper(), c_name, signed) + names.append(name) + populatelist.append((name.upper(), c_name, signed)) + platform.populate_inttypes(populatelist) + return names + +def setup(): + """ creates necessary c-level types + """ + names = populate_inttypes() + result = [] + for name in names: + tp = platform.types[name.upper()] globals()['r_' + name] = platform.numbertype_to_rclass[tp] globals()[name.upper()] = tp tpp = lltype.Ptr(lltype.Array(tp, hints={'nolength': True})) Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_ll2ctypes.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Wed Mar 31 00:17:06 2010 @@ -1041,6 +1041,10 @@ #assert lltype.cast_ptr_to_int(ref1) == intval + def test_ptr_truth(self): + abc = rffi.cast(lltype.Ptr(lltype.FuncType([], lltype.Void)), 0) + assert not abc + def test_mixed_gcref_comparison(self): NODE = lltype.GcStruct('NODE') node = lltype.malloc(NODE) Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_llgroup.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_llgroup.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/test/test_llgroup.py Wed Mar 31 00:17:06 2010 @@ -67,10 +67,11 @@ test.build() grpptr = test.grpptr g1x = [test.g1a, test.g1b] - cs1 = CombinedSymbolic(test.g1b, 0x450000) - cs2 = CombinedSymbolic(test.g1b, 0x410000) - assert llop.extract_ushort(rffi.USHORT, cs1) is test.g1b - assert cs1 & ~0xFFFF == 0x450000 + MASK = CombinedSymbolic.MASK + cs1 = CombinedSymbolic(test.g1b, 0x45 << HALFSHIFT) + cs2 = CombinedSymbolic(test.g1b, 0x41 << HALFSHIFT) + assert llop.extract_ushort(HALFWORD, cs1) is test.g1b + assert cs1 & ~MASK == 0x45 << HALFSHIFT cslist = [cs1, cs2] # def f(): @@ -99,11 +100,11 @@ assert p.x == expected[i] # for i in range(2): - s = llop.extract_ushort(rffi.USHORT, cslist[i]) + s = llop.extract_ushort(HALFWORD, cslist[i]) p = llop.get_group_member(lltype.Ptr(test.S1), grpptr, s) assert p == test.p1b - assert cslist[0] & ~0xFFFF == 0x450000 - assert cslist[1] & ~0xFFFF == 0x410000 + assert cslist[0] & ~MASK == 0x45 << HALFSHIFT + assert cslist[1] & ~MASK == 0x41 << HALFSHIFT # return 42 return f Modified: pypy/branch/cpython-extension/pypy/rpython/memory/gc/generation.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/memory/gc/generation.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/memory/gc/generation.py Wed Mar 31 00:17:06 2010 @@ -8,9 +8,11 @@ from pypy.rlib.objectmodel import free_non_gc_object from pypy.rlib.debug import ll_assert from pypy.rlib.debug import debug_print, debug_start, debug_stop -from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import intmask, LONG_BIT from pypy.rpython.lltypesystem.lloperation import llop +WORD = LONG_BIT // 8 + # The following flag is never set on young objects, i.e. the ones living # in the nursery. It is initially set on all prebuilt and old objects, # and gets cleared by the write_barrier() when we write in them a @@ -47,10 +49,10 @@ nursery_hash_base = -1 def __init__(self, config, chunk_size=DEFAULT_CHUNK_SIZE, - nursery_size=128, - min_nursery_size=128, + nursery_size=32*WORD, + min_nursery_size=32*WORD, auto_nursery_size=False, - space_size=4096, + space_size=1024*WORD, max_space_size=sys.maxint//2+1): SemiSpaceGC.__init__(self, config, chunk_size = chunk_size, space_size = space_size, Modified: pypy/branch/cpython-extension/pypy/rpython/memory/gc/hybrid.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/memory/gc/hybrid.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/memory/gc/hybrid.py Wed Mar 31 00:17:06 2010 @@ -1,6 +1,6 @@ import sys from pypy.rpython.memory.gc.semispace import SemiSpaceGC -from pypy.rpython.memory.gc.generation import GenerationGC +from pypy.rpython.memory.gc.generation import GenerationGC, WORD from pypy.rpython.memory.gc.semispace import GCFLAG_EXTERNAL, GCFLAG_FORWARDED from pypy.rpython.memory.gc.semispace import GCFLAG_HASHMASK from pypy.rpython.memory.gc.generation import GCFLAG_NO_YOUNG_PTRS @@ -89,8 +89,8 @@ # condition: large_object <= large_object_gcptrs < min_nursery_size/4 def __init__(self, *args, **kwds): - large_object = kwds.pop('large_object', 24) - large_object_gcptrs = kwds.pop('large_object_gcptrs', 32) + large_object = kwds.pop('large_object', 6*WORD) + large_object_gcptrs = kwds.pop('large_object_gcptrs', 8*WORD) self.generation3_collect_threshold = kwds.pop( 'generation3_collect_threshold', GENERATION3_COLLECT_THRESHOLD) GenerationGC.__init__(self, *args, **kwds) Modified: pypy/branch/cpython-extension/pypy/rpython/memory/gc/test/test_direct.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/memory/gc/test/test_direct.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/memory/gc/test/test_direct.py Wed Mar 31 00:17:06 2010 @@ -9,6 +9,9 @@ import py from pypy.rpython.lltypesystem import lltype, llmemory from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder +from pypy.rlib.rarithmetic import LONG_BIT + +WORD = LONG_BIT // 8 ADDR_ARRAY = lltype.Array(llmemory.Address) S = lltype.GcForwardReference() @@ -378,11 +381,11 @@ class TestHybridGC(TestGenerationGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass - GC_PARAMS = {'space_size': 192, - 'min_nursery_size': 48, - 'nursery_size': 48, - 'large_object': 12, - 'large_object_gcptrs': 12, + GC_PARAMS = {'space_size': 48*WORD, + 'min_nursery_size': 12*WORD, + 'nursery_size': 12*WORD, + 'large_object': 3*WORD, + 'large_object_gcptrs': 3*WORD, 'generation3_collect_threshold': 5, } Modified: pypy/branch/cpython-extension/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/memory/test/test_gc.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,6 @@ import py import sys -#from pypy.rpython.memory.support import INT_SIZE from pypy.rpython.memory import gcwrapper from pypy.rpython.memory.test import snippet from pypy.rpython.test.test_llinterp import get_interpreter @@ -12,6 +11,10 @@ from pypy.rlib.objectmodel import compute_unique_id, keepalive_until_here from pypy.rlib import rgc from pypy.rlib.rstring import StringBuilder +from pypy.rlib.rarithmetic import LONG_BIT + +WORD = LONG_BIT // 8 + def stdout_ignore_ll_functions(msg): strmsg = str(msg) @@ -629,7 +632,7 @@ GC_CAN_SHRINK_ARRAY = True class TestGrowingSemiSpaceGC(TestSemiSpaceGC): - GC_PARAMS = {'space_size': 64} + GC_PARAMS = {'space_size': 16*WORD} class TestGenerationalGC(TestSemiSpaceGC): from pypy.rpython.memory.gc.generation import GenerationGC as GCClass @@ -641,7 +644,7 @@ py.test.skip("Not implemented yet") class TestMarkCompactGCGrowing(TestMarkCompactGC): - GC_PARAMS = {'space_size': 64} + GC_PARAMS = {'space_size': 16*WORD} class TestHybridGC(TestGenerationalGC): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass @@ -716,11 +719,11 @@ GC_CAN_MOVE = False # with this size of heap, stuff gets allocated # in 3rd gen. GC_CANNOT_MALLOC_NONMOVABLE = False - GC_PARAMS = {'space_size': 192, - 'min_nursery_size': 48, - 'nursery_size': 48, - 'large_object': 12, - 'large_object_gcptrs': 12, + GC_PARAMS = {'space_size': 48*WORD, + 'min_nursery_size': 12*WORD, + 'nursery_size': 12*WORD, + 'large_object': 3*WORD, + 'large_object_gcptrs': 3*WORD, 'generation3_collect_threshold': 5, } Modified: pypy/branch/cpython-extension/pypy/rpython/memory/test/test_transformed_gc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/memory/test/test_transformed_gc.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/memory/test/test_transformed_gc.py Wed Mar 31 00:17:06 2010 @@ -1,10 +1,10 @@ import py import sys -import struct, inspect +import inspect from pypy.translator.c import gc from pypy.annotation import model as annmodel from pypy.annotation import policy as annpolicy -from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi +from pypy.rpython.lltypesystem import lltype, llmemory, llarena, rffi, llgroup from pypy.rpython.memory.gctransform import framework from pypy.rpython.lltypesystem.lloperation import llop, void from pypy.rpython.memory.gc.marksweep import X_CLONE, X_POOL, X_POOL_PTR @@ -14,8 +14,9 @@ from pypy import conftest from pypy.rlib.rstring import StringBuilder from pypy.rlib.objectmodel import keepalive_until_here +from pypy.rlib.rarithmetic import LONG_BIT -INT_SIZE = struct.calcsize("i") # only for estimates +WORD = LONG_BIT // 8 def rtype(func, inputtypes, specialize=True, gcname='ref', stacklessgc=False, @@ -219,7 +220,7 @@ run, statistics = self.runner("llinterp_lists", statistics=True) run([]) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def define_llinterp_tuples(cls): def malloc_a_lot(): @@ -239,7 +240,7 @@ run, statistics = self.runner("llinterp_tuples", statistics=True) run([]) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def skipdefine_global_list(cls): gl = [] @@ -275,7 +276,7 @@ res = run([100, 0]) assert res == len(''.join([str(x) for x in range(100)])) heap_size = self.heap_usage(statistics) - assert heap_size < 16000 * INT_SIZE / 4 # xxx + assert heap_size < 16000 * WORD / 4 # xxx def define_nongc_static_root(cls): T1 = lltype.GcStruct("C", ('x', lltype.Signed)) @@ -687,7 +688,7 @@ def f(): from pypy.rpython.lltypesystem import rffi alist = [A() for i in range(50)] - idarray = lltype.malloc(rffi.INTP.TO, len(alist), flavor='raw') + idarray = lltype.malloc(rffi.LONGP.TO, len(alist), flavor='raw') # Compute the id of all the elements of the list. The goal is # to not allocate memory, so that if the GC needs memory to # remember the ids, it will trigger some collections itself @@ -753,7 +754,7 @@ graph = graphof(translator, g) for op in graph.startblock.operations: if op.opname == 'do_malloc_fixedsize_clear': - op.args = [Constant(type_id, rffi.USHORT), + op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), Constant(True, lltype.Bool), # can_collect Constant(False, lltype.Bool), # has_finalizer @@ -790,7 +791,7 @@ graph = graphof(translator, g) for op in graph.startblock.operations: if op.opname == 'do_malloc_fixedsize_clear': - op.args = [Constant(type_id, rffi.USHORT), + op.args = [Constant(type_id, llgroup.HALFWORD), Constant(llmemory.sizeof(P), lltype.Signed), Constant(True, lltype.Bool), # can_collect Constant(False, lltype.Bool), # has_finalizer @@ -883,7 +884,7 @@ gcname = "marksweep" class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 @@ -1121,7 +1122,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.marksweep import PrintingMarkSweepGC as GCClass - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 class TestSemiSpaceGC(GenericMovingGCTests): @@ -1131,7 +1132,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.semispace import SemiSpaceGC as GCClass - GC_PARAMS = {'space_size': 2048} + GC_PARAMS = {'space_size': 512*WORD} root_stack_depth = 200 class TestMarkCompactGC(GenericMovingGCTests): @@ -1143,7 +1144,7 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.markcompact import MarkCompactGC as GCClass - GC_PARAMS = {'space_size': 2048} + GC_PARAMS = {'space_size': 512*WORD} root_stack_depth = 200 class TestGenerationGC(GenericMovingGCTests): @@ -1154,8 +1155,8 @@ class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.generation import GenerationGC as \ GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD} root_stack_depth = 200 def define_weakref_across_minor_collection(cls): @@ -1351,8 +1352,8 @@ self.__ready = False # collecting here is expected GenerationGC._teardown(self) - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 512} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 128*WORD} root_stack_depth = 200 def define_working_nursery(cls): @@ -1382,9 +1383,9 @@ class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.hybrid import HybridGC as GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128, - 'large_object': 32} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD, + 'large_object': 8*WORD} root_stack_depth = 200 def define_ref_from_rawmalloced_to_regular(cls): @@ -1522,7 +1523,7 @@ gcname = "marksweep" class gcpolicy(gc.FrameworkGcPolicy): class transformerclass(framework.FrameworkGCTransformer): - GC_PARAMS = {'start_heap_size': 4096 } + GC_PARAMS = {'start_heap_size': 1024*WORD } root_stack_depth = 200 class TestHybridTaggedPointerGC(TaggedPointerGCTests): @@ -1532,6 +1533,6 @@ class transformerclass(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.generation import GenerationGC as \ GCClass - GC_PARAMS = {'space_size': 2048, - 'nursery_size': 128} + GC_PARAMS = {'space_size': 512*WORD, + 'nursery_size': 32*WORD} root_stack_depth = 200 Modified: pypy/branch/cpython-extension/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/test/test_rbuiltin.py Wed Mar 31 00:17:06 2010 @@ -5,7 +5,8 @@ from pypy.rlib.debug import llinterpcall from pypy.rpython.lltypesystem import lltype from pypy.tool import udir -from pypy.rlib.rarithmetic import r_uint, intmask, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import intmask +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong from pypy.annotation.builtin import * from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rpython.lltypesystem import rffi @@ -526,11 +527,21 @@ return rffi.cast(rffi.VOIDP, v) res = self.interpret(llfn, [r_ulonglong(0)]) assert res == lltype.nullptr(rffi.VOIDP.TO) + # def llfn(v): return rffi.cast(rffi.LONGLONG, v) res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) assert res == 0 - assert isinstance(res, r_longlong) + if r_longlong is not r_int: + assert isinstance(res, r_longlong) + else: + assert isinstance(res, int) + # + def llfn(v): + return rffi.cast(rffi.ULONGLONG, v) + res = self.interpret(llfn, [lltype.nullptr(rffi.VOIDP.TO)]) + assert res == 0 + assert isinstance(res, r_ulonglong) class TestOOtype(BaseTestRbuiltin, OORtypeMixin): Modified: pypy/branch/cpython-extension/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/test/test_rdict.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/test/test_rdict.py Wed Mar 31 00:17:06 2010 @@ -4,7 +4,7 @@ from pypy.rpython.lltypesystem import rdict, rstr from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin from pypy.rlib.objectmodel import r_dict -from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong +from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong import py py.log.setconsumer("rtyper", py.log.STDOUT) @@ -567,6 +567,8 @@ def test_dict_of_r_uint(self): for r_t in [r_uint, r_longlong, r_ulonglong]: + if r_t is r_int: + continue # for 64-bit platforms: skip r_longlong d = {r_t(2): 3, r_t(4): 5} def fn(x, y): d[r_t(x)] = 123 Modified: pypy/branch/cpython-extension/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/test/test_rint.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/test/test_rint.py Wed Mar 31 00:17:06 2010 @@ -110,10 +110,10 @@ def f(i): return str(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert self.ll_to_string(res) == '0' - res = self.interpret(f, [r_longlong(413974738222117)]) + res = self.interpret(f, [int64(413974738222117)]) assert self.ll_to_string(res) == '413974738222117' def test_unsigned(self): @@ -135,7 +135,7 @@ f._annspecialcase_ = "specialize:argtype(0)" def g(n): if n > 0: - return f(r_longlong(0)) + return f(int64(0)) else: return f(0) res = self.interpret(g, [0]) @@ -147,7 +147,7 @@ def test_downcast_int(self): def f(i): return int(i) - res = self.interpret(f, [r_longlong(0)]) + res = self.interpret(f, [int64(0)]) assert res == 0 def test_isinstance_vs_int_types(self): Modified: pypy/branch/cpython-extension/pypy/rpython/tool/rffi_platform.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/tool/rffi_platform.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/tool/rffi_platform.py Wed Mar 31 00:17:06 2010 @@ -299,11 +299,16 @@ fieldoffsets.append(offset) seen[cell] = True + allfields = tuple(['c_' + name for name, _ in fields]) + padfields = tuple(padfields) name = self.name + padding_drop = PaddingDrop(name, allfields, padfields, + config_result.CConfig._compilation_info_) hints = {'align': info['align'], 'size': info['size'], 'fieldoffsets': tuple(fieldoffsets), - 'padding': tuple(padfields)} + 'padding': padfields, + 'get_padding_drop': padding_drop} if name.startswith('struct '): name = name[7:] else: @@ -477,6 +482,89 @@ return info['size'] # ____________________________________________________________ + +class PaddingDrop(object): + # Compute (lazily) the padding_drop for a structure. + # See test_generate_padding for more information. + cache = None + + def __init__(self, name, allfields, padfields, eci): + self.name = name + self.allfields = allfields + self.padfields = padfields + self.eci = eci + + def __call__(self, types): + if self.cache is None: + self.compute_now(types) + return self.cache + + def compute_now(self, types): + # Some simplifying assumptions there. We assume that all fields + # are either integers or pointers, so can be written in C as '0'. + # We also assume that the C backend gives us in 'types' a dictionary + # mapping non-padding field names to their C type (without '@'). + drops = [] + staticfields = [] + consecutive_pads = [] + for fieldname in self.allfields: + if fieldname in self.padfields: + consecutive_pads.append(fieldname) + continue + staticfields.append(types[fieldname]) + if consecutive_pads: + # In that case we have to ask: how many of these pads are + # really needed? The correct answer might be between none + # and all of the pads listed in 'consecutive_pads'. + for i in range(len(consecutive_pads)+1): + class CConfig: + _compilation_info_ = self.eci + FIELDLOOKUP = _PaddingDropFieldLookup(self.name, + staticfields, + fieldname) + try: + got = configure(CConfig)['FIELDLOOKUP'] + if got == 1: + break # found + except CompilationError: + pass + staticfields.insert(-1, None) + else: + raise Exception("could not determine the detailed field" + " layout of %r" % (self.name,)) + # succeeded with 'i' pads. Drop all pads beyond that. + drops += consecutive_pads[i:] + consecutive_pads = [] + drops += consecutive_pads # drop the final pads too + self.cache = drops + +class _PaddingDropFieldLookup(CConfigEntry): + def __init__(self, name, staticfields, fieldname): + self.name = name + self.staticfields = staticfields + self.fieldname = fieldname + + def prepare_code(self): + yield 'typedef %s platcheck_t;' % (self.name,) + yield 'static platcheck_t s = {' + for i, type in enumerate(self.staticfields): + if i == len(self.staticfields)-1: + value = -1 + else: + value = 0 + if type: + yield '\t(%s)%s,' % (type, value) + else: + yield '\t%s,' % (value,) + yield '};' + fieldname = self.fieldname + assert fieldname.startswith('c_') + yield 'dump("fieldlookup", s.%s != 0);' % (fieldname[2:],) + + def build_result(self, info, config_result): + return info['fieldlookup'] + +# ____________________________________________________________ # # internal helpers Modified: pypy/branch/cpython-extension/pypy/rpython/tool/rfficache.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/tool/rfficache.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/tool/rfficache.py Wed Mar 31 00:17:06 2010 @@ -13,7 +13,7 @@ from pypy.tool.gcc_cache import build_executable_cache def ask_gcc(question, add_source=""): - includes = ['stdlib.h', 'sys/types.h'] + includes = ['stdlib.h', 'stdio.h', 'sys/types.h'] include_string = "\n".join(["#include <%s>" % i for i in includes]) c_source = py.code.Source(''' // includes @@ -34,12 +34,22 @@ return build_executable_cache([c_file], eci) def sizeof_c_type(c_typename, **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]) + return sizeof_c_types([c_typename], **kwds)[0] + +def sizeof_c_types(typenames_c, **kwds): + lines = ['printf("sizeof %s=%%ld\\n", (long)sizeof(%s));' % (c_typename, + c_typename) + for c_typename in typenames_c] + question = '\n\t'.join(lines) + answer = ask_gcc(question, **kwds) + lines = answer.splitlines() + assert len(lines) == len(typenames_c) + result = [] + for line, c_typename in zip(lines, typenames_c): + answer = line.split('=') + assert answer[0] == "sizeof " + c_typename + result.append(int(answer[1])) + return result class Platform: def __init__(self): @@ -50,11 +60,28 @@ try: return self.types[name] except KeyError: - bits = sizeof_c_type(c_name, **kwds) * 8 - inttype = rarithmetic.build_int('r_' + name, signed, bits) - tp = lltype.build_number(name, inttype) - self.numbertype_to_rclass[tp] = inttype - self.types[name] = tp - return tp + size = sizeof_c_type(c_name, **kwds) + return self._make_type(name, signed, size) + + def _make_type(self, name, signed, size): + inttype = rarithmetic.build_int('r_' + name, signed, size*8) + tp = lltype.build_number(name, inttype) + self.numbertype_to_rclass[tp] = inttype + self.types[name] = tp + return tp + + def populate_inttypes(self, list, **kwds): + """'list' is a list of (name, c_name, signed).""" + missing = [] + names_c = [] + for name, c_name, signed in list: + if name not in self.types: + missing.append((name, signed)) + names_c.append(c_name) + if names_c: + sizes = sizeof_c_types(names_c, **kwds) + assert len(sizes) == len(missing) + for (name, signed), size in zip(missing, sizes): + self._make_type(name, signed, size) platform = Platform() Modified: pypy/branch/cpython-extension/pypy/rpython/tool/test/test_rffi_platform.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/tool/test/test_rffi_platform.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/tool/test/test_rffi_platform.py Wed Mar 31 00:17:06 2010 @@ -256,3 +256,104 @@ library_dirs = [str(tmpdir)] ) rffi_platform.verify_eci(eci) + +def test_generate_padding(): + # 'padding_drop' is a bit strange, but is what we need to write C code + # that defines prebuilt structures of that type. Normally, the C + # backend would generate '0' entries for every field c__pad#. That's + # usually much more than the number of real fields in the real structure + # definition. So 'padding_drop' allows a quick fix: it lists fields + # that should be ignored by the C backend. It should only be used in + # that situation because it lists some of the c__pad# fields a bit + # randomly -- to the effect that writing '0' for the other fields gives + # the right amount of '0's. + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad0'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0',) + d = {'c_c1': 'char', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == [] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + char c3; /* _pad1 */ + /* _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + /* _pad0 */ + short s1; /* _pad1, _pad2 */ + int i1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2') + d = {'c_c1': 'char', 'c_i1': 'int'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + char c2; /* _pad0 */ + /* _pad1, _pad2 */ + int i1; + char c3; /* _pad3 */ + /* _pad4 */ + short s1; + } foobar_t; + """, [("c1", lltype.Signed), + ("i1", lltype.Signed), + ("s1", lltype.Signed)]) + assert S._hints['padding'] == ('c__pad0', 'c__pad1', 'c__pad2', + 'c__pad3', 'c__pad4') + d = {'c_c1': 'char', 'c_i1': 'int', 'c_s1': 'short'} + assert S._hints['get_padding_drop'](d) == ['c__pad1', 'c__pad2', 'c__pad4'] + # + S = rffi_platform.getstruct("foobar_t", """ + typedef struct { + char c1; + long l2; /* some number of _pads */ + } foobar_t; + """, [("c1", lltype.Signed)]) + padding = list(S._hints['padding']) + d = {'c_c1': 'char'} + assert S._hints['get_padding_drop'](d) == padding Modified: pypy/branch/cpython-extension/pypy/tool/terminal.py ============================================================================== --- pypy/branch/cpython-extension/pypy/tool/terminal.py (original) +++ pypy/branch/cpython-extension/pypy/tool/terminal.py Wed Mar 31 00:17:06 2010 @@ -25,8 +25,8 @@ # List of numeric capabilities VALUES = { - 'COLUMNS':'cols', # Width of the terminal (None for unknown) - 'LINES':'lines', # Height of the terminal (None for unknown) + 'COLUMNS':'cols', # Width of the terminal (80 for unknown) + 'LINES':'lines', # Height of the terminal (25 for unknown) 'MAX_COLORS': 'colors', } @@ -37,8 +37,9 @@ setattr(MODULE, 'BG_%s' % color, '') for control in CONTROLS: setattr(MODULE, control, '') - for value in VALUES: - setattr(MODULE, value, None) + MODULE.COLUMNS = 80 + MODULE.LINES = 25 + MODULE.MAX_COLORS = 1 def setup(): """Set the terminal control strings""" Modified: pypy/branch/cpython-extension/pypy/translator/c/gcc/test/conftest.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/gcc/test/conftest.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/gcc/test/conftest.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,9 @@ import py from pypy.jit.backend import detect_cpu -class Directory(py.test.collect.Directory): +class Module(py.test.collect.Module): def collect(self): cpu = detect_cpu.autodetect() if cpu != 'x86': py.test.skip("x86 directory skipped: cpu is %r" % (cpu,)) - return super(Directory, self).collect() + return super(Module, self).collect() Modified: pypy/branch/cpython-extension/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/genc.py Wed Mar 31 00:17:06 2010 @@ -174,16 +174,19 @@ have___thread = None + def merge_eci(self, *ecis): + self.eci = self.eci.merge(*ecis) + def collect_compilation_info(self, db): # we need a concrete gcpolicy to do this - self.eci = self.eci.merge(db.gcpolicy.compilation_info()) + self.merge_eci(db.gcpolicy.compilation_info()) all = [] for node in self.db.globalcontainers(): eci = getattr(node, 'compilation_info', None) if eci: all.append(eci) - self.eci = self.eci.merge(*all) + self.merge_eci(*all) def get_gcpolicyclass(self): if self.gcpolicy is None: Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/node.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/node.py Wed Mar 31 00:17:06 2010 @@ -11,6 +11,7 @@ from pypy.translator.c.support import c_char_array_constant, barebonearray from pypy.translator.c.primitive import PrimitiveType, name_signed from pypy.rlib.rarithmetic import isinf, isnan +from pypy.rlib.rstackovf import _StackOverflow from pypy.translator.c import extfunc from pypy.translator.tool.cbuild import ExternalCompilationInfo from py.builtin import BaseException @@ -37,6 +38,8 @@ class StructDefNode: typetag = 'struct' + extra_union_for_varlength = True + def __init__(self, db, STRUCT, varlength=1): self.db = db self.STRUCT = STRUCT @@ -82,7 +85,8 @@ self.fields = [] db = self.db STRUCT = self.STRUCT - varlength = self.varlength + if self.varlength != 1: + self.normalizedtypename = db.gettype(STRUCT, who_asks=self) if needs_gcheader(self.STRUCT): for fname, T in db.gcpolicy.struct_gcheader_definition(self): self.fields.append((fname, db.gettype(T, who_asks=self))) @@ -151,6 +155,12 @@ if is_empty: yield '\t' + 'char _dummy; /* this struct is empty */' yield '};' + if self.varlength != 1: + assert self.typetag == 'struct' + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_field): for name in self.fieldnames: @@ -162,6 +172,7 @@ def debug_offsets(self): # generate number exprs giving the offset of the elements in the struct + assert self.varlength == 1 for name in self.fieldnames: FIELD_T = self.c_struct_field_type(name) if FIELD_T is Void: @@ -178,15 +189,15 @@ class ArrayDefNode: typetag = 'struct' + extra_union_for_varlength = True def __init__(self, db, ARRAY, varlength=1): self.db = db self.ARRAY = ARRAY self.LLTYPE = ARRAY - original_varlength = varlength self.gcfields = [] self.varlength = varlength - if original_varlength == 1: + if varlength == 1: basename = 'array' with_number = True else: @@ -204,6 +215,8 @@ db = self.db ARRAY = self.ARRAY self.gcinfo # force it to be computed + if self.varlength != 1: + self.normalizedtypename = db.gettype(ARRAY, who_asks=self) if needs_gcheader(ARRAY): for fname, T in db.gcpolicy.array_gcheader_definition(self): self.gcfields.append((fname, db.gettype(T, who_asks=self))) @@ -227,7 +240,7 @@ return '%s.items[%s]' % (baseexpr, index) access_expr_varindex = access_expr - def ptr_access_expr(self, baseexpr, index): + def ptr_access_expr(self, baseexpr, index, dummy=False): assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,) return self.itemindex_access_expr(baseexpr, index) @@ -251,8 +264,14 @@ line = 'char _dummy; ' + line yield '\t' + line yield '};' + if self.varlength != 1: + yield 'union %su {' % self.name + yield ' struct %s a;' % self.name + yield ' %s;' % cdecl(self.normalizedtypename, 'b') + yield '};' def visitor_lines(self, prefix, on_item): + assert self.varlength == 1 ARRAY = self.ARRAY # we need a unique name for this C variable, or at least one that does # not collide with the expression in 'prefix' @@ -279,6 +298,7 @@ def debug_offsets(self): # generate three offsets for debugging inspection + assert self.varlength == 1 if not self.ARRAY._hints.get('nolength', False): yield 'offsetof(struct %s, length)' % (self.name,) else: @@ -299,6 +319,7 @@ gcinfo = None name = None forward_decl = None + extra_union_for_varlength = False def __init__(self, db, ARRAY, varlength=1): self.db = db @@ -325,7 +346,7 @@ return '%s[%d]' % (baseexpr, index) access_expr_varindex = access_expr - def ptr_access_expr(self, baseexpr, index): + def ptr_access_expr(self, baseexpr, index, dummy=False): assert 0 <= index <= sys.maxint, "invalid constant index %r" % (index,) return self.itemindex_access_expr(baseexpr, index) @@ -349,6 +370,7 @@ gcinfo = None name = None typetag = 'struct' + extra_union_for_varlength = False def __init__(self, db, FIXEDARRAY): self.db = db @@ -368,7 +390,7 @@ def getptrtype(self): return self.itemtypename.replace('@', '*@') - def access_expr(self, baseexpr, index): + def access_expr(self, baseexpr, index, dummy=False): if not isinstance(index, int): assert index.startswith('item') index = int(index[4:]) @@ -461,28 +483,42 @@ parentnode = db.getcontainernode(parent) defnode = db.gettypedefnode(parentnode.T) self.name = defnode.access_expr(parentnode.name, parentindex) - self.ptrname = '(&%s)' % self.name if self.typename != self.implementationtypename: - ptrtypename = db.gettype(Ptr(T)) - self.ptrname = '((%s)(void*)%s)' % (cdecl(ptrtypename, ''), - self.ptrname) + if db.gettypedefnode(T).extra_union_for_varlength: + self.name += '.b' + self.ptrname = '(&%s)' % self.name def is_thread_local(self): return hasattr(self.T, "_hints") and self.T._hints.get('thread_local') + def get_declaration(self): + if self.name[-2:] == '.b': + # xxx fish fish + assert self.implementationtypename.startswith('struct ') + assert self.implementationtypename.endswith(' @') + uniontypename = 'union %su @' % self.implementationtypename[7:-2] + return uniontypename, self.name[:-2] + else: + return self.implementationtypename, self.name + def forward_declaration(self): if llgroup.member_of_group(self.obj): return + type, name = self.get_declaration() yield '%s;' % ( - forward_cdecl(self.implementationtypename, - self.name, self.db.standalone, self.is_thread_local())) + forward_cdecl(type, name, self.db.standalone, + self.is_thread_local())) def implementation(self): if llgroup.member_of_group(self.obj): return [] lines = list(self.initializationexpr()) + type, name = self.get_declaration() + if name != self.name: + lines[0] = '{ ' + lines[0] # extra braces around the 'a' part + lines[-1] += ' }' # of the union lines[0] = '%s = %s' % ( - cdecl(self.implementationtypename, self.name, self.is_thread_local()), + cdecl(type, name, self.is_thread_local()), lines[0]) lines[-1] += ';' return lines @@ -536,7 +572,19 @@ if hasattr(self.T, "_hints") and self.T._hints.get('union'): data = data[0:1] + if 'get_padding_drop' in self.T._hints: + d = {} + for name, _ in data: + T = defnode.c_struct_field_type(name) + typename = self.db.gettype(T) + d[name] = cdecl(typename, '') + padding_drop = self.T._hints['get_padding_drop'](d) + else: + padding_drop = [] + for name, value in data: + if name in padding_drop: + continue c_expr = defnode.access_expr(self.name, name) lines = generic_initializationexpr(self.db, value, c_expr, decoration + name) @@ -560,6 +608,7 @@ return 'struct _hashT_%s @' % self.name def forward_declaration(self): + assert self.typename == self.implementationtypename # no array part hash_typename = self.get_hash_typename() hash_offset = self.db.gctransformer.get_hash_offset(self.T) yield '%s {' % cdecl(hash_typename, '') @@ -675,6 +724,7 @@ return 1 # not variable-sized! def initializationexpr(self, decoration=''): + assert self.typename == self.implementationtypename # not var-sized is_empty = True yield '{' # _names == ['item0', 'item1', ...] @@ -928,9 +978,12 @@ import types, py if isinstance(value, (type, types.ClassType)): if (issubclass(value, BaseException) and - (value.__module__ == 'exceptions' - or value is py.code._AssertionError)): + value.__module__ == 'exceptions'): return 'PyExc_' + value.__name__ + if value is py.code._AssertionError: + return 'PyExc_AssertionError' + if value is _StackOverflow: + return 'PyExc_RuntimeError' raise Exception("don't know how to simply render py object: %r" % (value, )) @@ -991,18 +1044,13 @@ forward_cdecl(ctype, self.name, self.db.standalone, self.is_thread_local())) yield '#include "src/llgroup.h"' + yield 'PYPY_GROUP_CHECK_SIZE(%s)' % (self.name,) for i, member in enumerate(self.obj.members): structnode = self.db.getcontainernode(member) yield '#define %s %s.member%d' % (structnode.name, self.name, i) yield '' - def startupcode(self): - count = len(self.obj.members) - if count == 0: - return [] - return ['PYPY_GROUP_CHECK_SIZE(%s, member%d);' % (self.name, count-1)] - def initializationexpr(self): self._fix_members() lines = ['{'] Modified: pypy/branch/cpython-extension/pypy/translator/c/primitive.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/primitive.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/primitive.py Wed Mar 31 00:17:06 2010 @@ -148,9 +148,8 @@ if isinstance(value, Symbolic): if isinstance(value, llgroup.GroupMemberOffset): groupnode = db.getcontainernode(value.grpptr._as_obj()) - return 'GROUP_MEMBER_OFFSET(%s, %s, member%s)' % ( + return 'GROUP_MEMBER_OFFSET(%s, member%s)' % ( cdecl(groupnode.implementationtypename, ''), - groupnode.name, value.index, ) else: Modified: pypy/branch/cpython-extension/pypy/translator/c/src/commondefs.h ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/src/commondefs.h (original) +++ pypy/branch/cpython-extension/pypy/translator/c/src/commondefs.h Wed Mar 31 00:17:06 2010 @@ -76,3 +76,7 @@ #define HAVE_LONG_LONG 1 #define Py_HUGE_VAL HUGE_VAL + +#ifdef _WIN32 +# define MS_WINDOWS /* a synonym */ +#endif Modified: pypy/branch/cpython-extension/pypy/translator/c/src/exception.h ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/src/exception.h (original) +++ pypy/branch/cpython-extension/pypy/translator/c/src/exception.h Wed Mar 31 00:17:06 2010 @@ -99,14 +99,21 @@ assert(RPyExceptionOccurred()); assert(!PyErr_Occurred()); clsname = RPyFetchExceptionType()->ov_name->items; - pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); - if (pycls != NULL && PyExceptionClass_Check(pycls) && - PyObject_IsSubclass(pycls, PyExc_Exception)) { - v = NULL; + v = NULL; + if (strcmp(clsname, "AssertionError") == 0) { + /* workaround against the py lib's BuiltinAssertionError */ + pycls = PyExc_AssertionError; + } + else if (strcmp(clsname, "StackOverflow") == 0) { + pycls = PyExc_RuntimeError; } else { - pycls = PyExc_Exception; /* XXX RPythonError */ - v = PyString_FromString(clsname); + pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); + if (pycls == NULL || !PyExceptionClass_Check(pycls) || + !PyObject_IsSubclass(pycls, PyExc_Exception)) { + pycls = PyExc_Exception; /* XXX RPythonError */ + v = PyString_FromString(clsname); + } } Py_INCREF(pycls); tb = NULL; Modified: pypy/branch/cpython-extension/pypy/translator/c/src/llgroup.h ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/src/llgroup.h (original) +++ pypy/branch/cpython-extension/pypy/translator/c/src/llgroup.h Wed Mar 31 00:17:06 2010 @@ -11,7 +11,7 @@ typedef unsigned short pypy_halfword_t; -#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ +#define GROUP_MEMBER_OFFSET(grouptype, membername) \ ((unsigned short)(((long)&((grouptype*)NULL)->membername) / 4)) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ @@ -22,33 +22,31 @@ /* A macro to crash at compile-time if sizeof(group) is too large. Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - { typedef char group_##groupname##_is_too_large[ \ - 2*(sizeof(groupname) <= 65536*4)-1]; } +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 65536*4)-1]; #else /******************************************************/ /* On 64-bit platforms, a CombinedSymbolic is two UINTs, and the lower - one stores a real pointer to the group memeber. The limitation is - that this pointer must fit inside 32-bit, i.e. the whole group must - be located in the first 32 bits of address space. */ + one is an 32-bit offset from the start of the group. */ typedef unsigned int pypy_halfword_t; -#define GROUP_MEMBER_OFFSET(grouptype, groupname, membername) \ - ((long)(&groupname.membername)) +#define GROUP_MEMBER_OFFSET(grouptype, membername) \ + offsetof(grouptype, membername) #define _OP_GET_GROUP_MEMBER(groupptr, compactoffset) \ - ((long)compactoffset) + (((char*)groupptr) + (long)compactoffset) #define _OP_GET_NEXT_GROUP_MEMBER(groupptr, compactoffset, skipoffset) \ - ((long)compactoffset + skipoffset) + (((char*)groupptr) + skipoffset + (long)compactoffset) -/* A macro to check at run-time if the group is below the 32-bit limit. */ -#define PYPY_GROUP_CHECK_SIZE(groupname, lastname) \ - if ((unsigned long)(&groupname.lastname) > 0xFFFFFFFF) \ - error = "group " #groupname " is not located in the " \ - "initial 32 bits of address space" +/* A macro to crash at compile-time if sizeof(group) is too large. + Uses a hack that I've found on some random forum. Haaaaaaaaaackish. */ +#define PYPY_GROUP_CHECK_SIZE(groupname) \ + typedef char group_##groupname##_is_too_large[ \ + 2*(sizeof(groupname) <= 4294967296L)-1]; #endif /*****************************************************/ Modified: pypy/branch/cpython-extension/pypy/translator/c/src/main.h ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/src/main.h (original) +++ pypy/branch/cpython-extension/pypy/translator/c/src/main.h Wed Mar 31 00:17:06 2010 @@ -15,6 +15,10 @@ #ifndef PYPY_NOT_MAIN_FILE +#ifdef MS_WINDOWS +#include "src/winstuff.c" +#endif + int main(int argc, char *argv[]) { char *errmsg; @@ -29,6 +33,10 @@ goto error; } +#ifdef MS_WINDOWS + pypy_Windows_startup(); +#endif + errmsg = RPython_StartupCode(); if (errmsg) goto error; Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_exception.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_exception.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_exception.py Wed Mar 31 00:17:06 2010 @@ -121,30 +121,16 @@ def testfn(n): assert n >= 0 - # big confusion with py.test's AssertionError handling here... - # some hacks to try to disable it for the current test. - saved = no_magic() - try: - f1 = getcompiled(testfn, [int]) - res = f1(0) - assert res is None, repr(res) - res = f1(42) - assert res is None, repr(res) - py.test.raises(AssertionError, f1, -2) - finally: - restore_magic(saved) - -def no_magic(): - import __builtin__ - try: - py.magic.revert(__builtin__, 'AssertionError') - return True - except ValueError: - return False - -def restore_magic(saved): - if saved: - py.magic.invoke(assertion=True) + f1 = getcompiled(testfn, [int]) + res = f1(0) + assert res is None, repr(res) + res = f1(42) + assert res is None, repr(res) + e = py.test.raises(Exception, f1, -2) + assert e.type.__name__ == 'AssertionError' + # ^^^ indirection, because we really want + # the original AssertionError and not the + # one patched by the py lib def test_reraise_exception(): Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_lltyped.py Wed Mar 31 00:17:06 2010 @@ -732,14 +732,17 @@ ('z4', Signed), ('u4', Signed)) goffsets = [] for i in range(4096 + toobig): - goffsets.append(grp.add_member(malloc(S1, immortal=True))) + ofs = grp.add_member(malloc(S1, immortal=True)) + goffsets.append(llgroup.CombinedSymbolic(ofs, 0)) grpptr = grp._as_ptr() def f(n): - p = llop.get_group_member(Ptr(S1), grpptr, goffsets[n]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[n]) + p = llop.get_group_member(Ptr(S1), grpptr, o) p.x = 5 for i in range(len(goffsets)): if i != n: - q = llop.get_group_member(Ptr(S1), grpptr, goffsets[i]) + o = llop.extract_ushort(llgroup.HALFWORD, goffsets[i]) + q = llop.get_group_member(Ptr(S1), grpptr, o) q.x = 666 return p.x if toobig: @@ -779,3 +782,48 @@ fn = self.getcompiled(f, []) res = fn() assert res == 42 + + def test_padding_in_prebuilt_struct(self): + from pypy.rpython.lltypesystem import rffi + from pypy.rpython.tool import rffi_platform + eci = rffi_platform.eci_from_header(""" + typedef struct { + char c1; /* followed by one byte of padding */ + short s1; + char c2; /* followed by 3 bytes of padding */ + int i2; + char c3; /* followed by 3 or 7 bytes of padding */ + long l3; + char c4; + } foobar_t; + """) + class CConfig: + _compilation_info_ = eci + STRUCT = rffi_platform.Struct("foobar_t", + [("c1", Signed), + ("s1", Signed), + ("l3", Signed)]) + S = rffi_platform.configure(CConfig)['STRUCT'] + assert 'get_padding_drop' in S._hints + s1 = malloc(S, immortal=True) + s1.c_c1 = rffi.cast(S.c_c1, -12) + s1.c_s1 = rffi.cast(S.c_s1, -7843) + s1.c_l3 = -98765432 + s2 = malloc(S, immortal=True) + s2.c_c1 = rffi.cast(S.c_c1, -123) + s2.c_s1 = rffi.cast(S.c_s1, -789) + s2.c_l3 = -9999999 + # + def f(n): + if n > 5: + s = s1 + else: + s = s2 + return s.c_l3 + # + self.include_also_eci = eci + fn = self.getcompiled(f, [int]) + res = fn(10) + assert res == -98765432 + res = fn(1) + assert res == -9999999 Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_newgc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_newgc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_newgc.py Wed Mar 31 00:17:06 2010 @@ -653,8 +653,8 @@ to_sort[2] = 1 to_sort[3] = 2 qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort)) - qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) qsort.push_arg(rffi.cast(rffi.SIZE_T, 4)) + qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG))) 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] Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_standalone.py Wed Mar 31 00:17:06 2010 @@ -590,6 +590,7 @@ class TestMaemo(TestStandalone): def setup_class(cls): + py.test.skip("TestMaemo: tests skipped for now") from pypy.translator.platform.maemo import check_scratchbox check_scratchbox() from pypy.config.pypyoption import get_pypy_config Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_typed.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_typed.py Wed Mar 31 00:17:06 2010 @@ -28,6 +28,8 @@ def compilefunc(self, t, func): from pypy.translator.c import genc self.builder = builder = genc.CExtModuleBuilder(t, func, config=t.config) + if hasattr(self, 'include_also_eci'): + builder.merge_eci(self.include_also_eci) builder.generate_source() builder.compile() return builder.get_entry_point() Modified: pypy/branch/cpython-extension/pypy/translator/exceptiontransform.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/exceptiontransform.py (original) +++ pypy/branch/cpython-extension/pypy/translator/exceptiontransform.py Wed Mar 31 00:17:06 2010 @@ -13,6 +13,7 @@ from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong from pypy.rlib.rarithmetic import r_singlefloat from pypy.rlib.debug import ll_assert +from pypy.rlib.rstackovf import _StackOverflow from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import MixLevelHelperAnnotator from pypy.tool.sourcetools import func_with_new_name @@ -60,8 +61,8 @@ exc_data, null_type, null_value = self.setup_excdata() rclass = translator.rtyper.type_system.rclass - (runtime_error_ll_exc_type, - runtime_error_ll_exc) = self.get_builtin_exception(RuntimeError) + (stackovf_ll_exc_type, + stackovf_ll_exc) = self.get_builtin_exception(_StackOverflow) (assertion_error_ll_exc_type, assertion_error_ll_exc) = self.get_builtin_exception(AssertionError) (n_i_error_ll_exc_type, @@ -114,8 +115,8 @@ exc_data.exc_type = rclass.ll_inst_type(evalue) exc_data.exc_value = evalue - def rpyexc_raise_runtime_error(): - rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc) + def rpyexc_raise_stack_overflow(): + rpyexc_raise(stackovf_ll_exc_type, stackovf_ll_exc) self.rpyexc_occured_ptr = self.build_func( "RPyExceptionOccurred", @@ -151,9 +152,9 @@ lltype.Void, jitcallkind='rpyexc_raise') # for the JIT - self.rpyexc_raise_runtime_error_ptr = self.build_func( - "RPyRaiseRuntimeError", - self.noinline(rpyexc_raise_runtime_error), + self.rpyexc_raise_stack_overflow_ptr = self.build_func( + "RPyRaiseStackOverflow", + self.noinline(rpyexc_raise_stack_overflow), [], lltype.Void) self.rpyexc_fetch_exception_ptr = self.build_func( @@ -237,10 +238,10 @@ if block.operations[i].opname == 'stack_unwind': # if there are stack_unwind ops left, # the graph was not stackless-transformed - # so we need to raise a RuntimeError in any + # so we need to raise a StackOverflow in any # case block.operations[i].opname = "direct_call" - block.operations[i].args = [self.rpyexc_raise_runtime_error_ptr] + block.operations[i].args = [self.rpyexc_raise_stack_overflow_ptr] def replace_fetch_restore_operations(self, block): # the gctransformer will create these operations. It looks as if the Modified: pypy/branch/cpython-extension/pypy/translator/goal/translate.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/goal/translate.py (original) +++ pypy/branch/cpython-extension/pypy/translator/goal/translate.py Wed Mar 31 00:17:06 2010 @@ -7,6 +7,12 @@ import sys, os, new import autopath +import py +# clean up early pypy/_cache +try: + py.path.local(autopath.pypydir).join('_cache').remove() +except Exception: + pass from pypy.config.config import to_optparse, OptionDescription, BoolOption, \ ArbitraryOption, StrOption, IntOption, Config, \ @@ -82,7 +88,6 @@ 'translation.debug': False, } -import py # we want 2.4 expand_default functionality import optparse from pypy.tool.ansi_print import ansi_log Modified: pypy/branch/cpython-extension/pypy/translator/jvm/test/test_backendopt.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/jvm/test/test_backendopt.py (original) +++ pypy/branch/cpython-extension/pypy/translator/jvm/test/test_backendopt.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,11 @@ import py from pypy.translator.jvm.test.runtest import JvmTest +from pypy.translator.jvm.genjvm import detect_missing_support_programs from pypy.translator.oosupport.test_template.backendopt import BaseTestOptimizedSwitch class TestOptimizedSwitch(BaseTestOptimizedSwitch): def getcompiled(self, fn, annotation): + detect_missing_support_programs() t = JvmTest() return t.compile(fn, None, annotation, backendopt=True) Modified: pypy/branch/cpython-extension/pypy/translator/jvm/test/test_rarithmetic.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/jvm/test/test_rarithmetic.py (original) +++ pypy/branch/cpython-extension/pypy/translator/jvm/test/test_rarithmetic.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,6 @@ import py from pypy.translator.jvm.test.runtest import JvmTest +from pypy.translator.jvm.genjvm import detect_missing_support_programs from pypy.rlib.test.test_rarithmetic import Test_r_uint as BaseTest_r_uint from pypy.rlib.test.test_rarithmetic import Test_r_int as BaseTest_r_int from pypy.rlib.test.test_rarithmetic import test_ovfcheck as base_test_ovfcheck @@ -8,6 +9,7 @@ class BaseAdaptedTest(JvmTest): def unary_test(self, f): + detect_missing_support_programs() cache = {} def new_func(x): xtype = type(x) @@ -20,6 +22,7 @@ super(BaseAdaptedTest,self).unary_test(new_func) def binary_test(self, f, rargs = None): + detect_missing_support_programs() cache = {} def new_func(x, y): if type(x) == self.RTYPE or type(y) == self.RTYPE: Modified: pypy/branch/cpython-extension/pypy/translator/platform/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/__init__.py Wed Mar 31 00:17:06 2010 @@ -10,21 +10,7 @@ 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 +from pypy.tool.runsubprocess import run_subprocess as _run_subprocess class CompilationError(Exception): def __init__(self, out, err): @@ -108,9 +94,10 @@ # some helpers which seem to be cross-platform enough - def _execute_c_compiler(self, cc, args, outname): + def _execute_c_compiler(self, cc, args, outname, cwd=None): log.execute(cc + ' ' + ' '.join(args)) - returncode, stdout, stderr = _run_subprocess(cc, args, self.c_environ) + returncode, stdout, stderr = _run_subprocess(cc, args, self.c_environ, + cwd) self._handle_error(returncode, stderr, stdout, outname) def _handle_error(self, returncode, stderr, stdout, outname): Modified: pypy/branch/cpython-extension/pypy/translator/platform/linux.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/linux.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/linux.py Wed Mar 31 00:17:06 2010 @@ -1,9 +1,7 @@ import py, os -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 +from pypy.translator.platform import _run_subprocess +from pypy.translator.platform.posix import BasePosix class Linux(BasePosix): name = "linux" @@ -19,10 +17,12 @@ return ['-shared'] + args def include_dirs_for_libffi(self): - return ['/usr/include/libffi'] + return self._pkg_config("libffi", "--cflags-only-I", + ['/usr/include/libffi']) def library_dirs_for_libffi(self): - return ['/usr/lib/libffi'] + return self._pkg_config("libffi", "--libs-only-L", + ['/usr/lib/libffi']) def library_dirs_for_libffi_a(self): # places where we need to look for libffi.a Modified: pypy/branch/cpython-extension/pypy/translator/platform/maemo.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/maemo.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/maemo.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,6 @@ import py, os -from pypy.translator.platform.linux import Linux, _run_subprocess, GnuMakefile +from pypy.translator.platform.linux import Linux +from pypy.translator.platform.posix import _run_subprocess, GnuMakefile from pypy.translator.platform import ExecutionResult, log from pypy.tool.udir import udir from pypy.tool import autopath Modified: pypy/branch/cpython-extension/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/posix.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/posix.py Wed Mar 31 00:17:06 2010 @@ -32,7 +32,8 @@ 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) + self._execute_c_compiler(cc, args, oname, + cwd=str(cfile.dirpath())) return oname def _link(self, cc, ofiles, link_args, standalone, exe_name): @@ -40,13 +41,24 @@ args += ['-o', str(exe_name)] if not standalone: args = self._args_for_shared(args) - self._execute_c_compiler(cc, args, exe_name) + self._execute_c_compiler(cc, args, exe_name, + cwd=str(exe_name.dirpath())) return exe_name def _preprocess_dirs(self, include_dirs): # hook for maemo return include_dirs + def _pkg_config(self, lib, opt, default): + try: + ret, out, err = _run_subprocess("pkg-config", [lib, opt]) + except OSError: + ret = 1 + if ret: + return default + # strip compiler flags + return [entry[2:] for entry in out.split()] + 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/cpython-extension/pypy/translator/platform/test/test_maemo.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/test/test_maemo.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/test/test_maemo.py Wed Mar 31 00:17:06 2010 @@ -13,6 +13,7 @@ strict_on_stderr = False def setup_class(cls): + py.test.skip("TestMaemo: tests skipped for now") check_scratchbox() def test_includes_outside_scratchbox(self): Modified: pypy/branch/cpython-extension/pypy/translator/platform/test/test_makefile.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/test/test_makefile.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/test/test_makefile.py Wed Mar 31 00:17:06 2010 @@ -1,5 +1,5 @@ -from pypy.translator.platform.linux import GnuMakefile as Makefile +from pypy.translator.platform.posix import GnuMakefile as Makefile from StringIO import StringIO import re Modified: pypy/branch/cpython-extension/pypy/translator/stackless/code.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/stackless/code.py (original) +++ pypy/branch/cpython-extension/pypy/translator/stackless/code.py Wed Mar 31 00:17:06 2010 @@ -1,7 +1,7 @@ import sys from pypy.rpython.lltypesystem import lltype, llmemory, lloperation from pypy.tool.sourcetools import func_with_new_name -from pypy.rlib import rarithmetic, objectmodel +from pypy.rlib import rarithmetic, objectmodel, rstackovf from pypy.translator.stackless import frame from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE, STORAGE_TYPES_AND_FIELDS @@ -382,7 +382,7 @@ # uncommon case: exceed the limit pending = pending.f_back pending.f_depth = depth - 1 - e = RuntimeError() + e = rstackovf._StackOverflow() if not pending: raise e global_state.exception = e From afa at codespeak.net Wed Mar 31 00:25:51 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 31 Mar 2010 00:25:51 +0200 (CEST) Subject: [pypy-svn] r73193 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100330222551.8454E282BD6@codespeak.net> Author: afa Date: Wed Mar 31 00:25:48 2010 New Revision: 73193 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Fix compilation on Windows Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 00:25:48 2010 @@ -547,7 +547,7 @@ newname = name pypy_macros.append('#define %s %s%s' % (name, deref, newname)) renamed_symbols.append(newname) - export_symbols = renamed_symbols + export_symbols[:] = renamed_symbols pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros)) @@ -593,7 +593,7 @@ separate_module_files=[include_dir / "varargwrapper.c", include_dir / "pyerrors.c", include_dir / "modsupport.c"], - export_symbols=export_symbols, + export_symbols=export_symbols_eci, **kwds ) return eci From xoraxax at codespeak.net Wed Mar 31 00:56:37 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 00:56:37 +0200 (CEST) Subject: [pypy-svn] r73194 - in pypy/branch/cpython-extension/pypy: rlib translator/c translator/c/test Message-ID: <20100330225637.34A62282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 00:56:34 2010 New Revision: 73194 Added: pypy/branch/cpython-extension/pypy/rlib/exports.py Modified: pypy/branch/cpython-extension/pypy/translator/c/genc.py pypy/branch/cpython-extension/pypy/translator/c/node.py pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Log: Add interface to export containers (currently only structs) in DLLs. Added: pypy/branch/cpython-extension/pypy/rlib/exports.py ============================================================================== --- (empty file) +++ pypy/branch/cpython-extension/pypy/rlib/exports.py Wed Mar 31 00:56:34 2010 @@ -0,0 +1,10 @@ +from pypy.rpython.lltypesystem.lltype import typeOf, ContainerType + +EXPORTS_names = set() +EXPORTS_obj2name = {} + +def export_struct(name, struct): + assert name not in EXPORTS_names, "Duplicate export " + name + assert isinstance(typeOf(struct), ContainerType) + EXPORTS_names.add(name) + EXPORTS_obj2name[struct] = name Modified: pypy/branch/cpython-extension/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/genc.py Wed Mar 31 00:56:34 2010 @@ -13,6 +13,7 @@ from pypy.translator.c.support import log, c_string_constant from pypy.rpython.typesystem import getfunctionptr from pypy.translator.c import gc +from pypy.rlib import exports def import_module_from_directory(dir, modname): file, pathname, description = imp.find_module(modname, [str(dir)]) @@ -167,6 +168,9 @@ db.get(getfunctionptr(bk.getdesc(func).getuniquegraph())) self.c_entrypoint_name = pfname + + for obj in exports.EXPORTS_obj2name.keys(): + db.getcontainernode(obj) db.complete() self.collect_compilation_info(db) Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/node.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/node.py Wed Mar 31 00:56:34 2010 @@ -10,6 +10,7 @@ from pypy.translator.c.support import cdecl, forward_cdecl, somelettersfrom from pypy.translator.c.support import c_char_array_constant, barebonearray from pypy.translator.c.primitive import PrimitiveType, name_signed +from pypy.rlib import exports from pypy.rlib.rarithmetic import isinf, isnan from pypy.rlib.rstackovf import _StackOverflow from pypy.translator.c import extfunc @@ -475,7 +476,10 @@ self.typename = db.gettype(T) #, who_asks=self) self.implementationtypename = db.gettype(T, varlength=self.getlength()) parent, parentindex = parentlink(obj) - if parent is None: + if obj in exports.EXPORTS_obj2name: + self.name = exports.EXPORTS_obj2name[obj] + self.globalcontainer = True + elif parent is None: self.name = db.namespace.uniquename('g_' + self.basename()) self.globalcontainer = True else: Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Wed Mar 31 00:56:34 2010 @@ -414,3 +414,18 @@ t.view() assert 'foobar' in t.driver.cbuilder.c_source_filename.read() +def test_exportstruct(): + from pypy.rlib.exports import export_struct + def f(): + return 42 + FOO = Struct("FOO", ("field1", Signed)) + foo = malloc(FOO, flavor="raw") + foo.field1 = 43 + export_struct("BarStruct", foo._obj) + t = Translation(f, [], backend="c") + t.annotate() + compiled_fn = t.compile_c() + if py.test.config.option.view: + t.view() + assert ' BarStruct ' in t.driver.cbuilder.c_source_filename.read() + From xoraxax at codespeak.net Wed Mar 31 00:59:12 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 00:59:12 +0200 (CEST) Subject: [pypy-svn] r73195 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100330225912.CF888282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 00:59:11 2010 New Revision: 73195 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Extend setup_library. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 00:59:11 2010 @@ -21,6 +21,7 @@ from pypy.rlib.entrypoint import entrypoint from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import specialize +from pypy.rlib.exports import export_struct # CPython 2.4 compatibility from py.builtin import BaseException @@ -599,7 +600,26 @@ return eci -def setup_library(space): +def setup_library(space, rename=False): + export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) + db = LowLevelDatabase() + + generate_macros(export_symbols, rename) + + generate_decls_and_callbacks(db) + + eci = build_eci(False, export_symbols) + + bootstrap_types(space) + + # populate static data + for name, (type, expr) in GLOBALS.iteritems(): + name = name.replace("#", "") + if rename: + name = name.replace('Py', 'PyPy') + w_obj = eval(expr) + export_struct(name, make_ref(space, w_obj)._obj) + for name, func in FUNCTIONS.iteritems(): deco = entrypoint("cpyext", func.argtypes, name, relax=True) deco(func.get_wrapper(space)) From xoraxax at codespeak.net Wed Mar 31 01:41:09 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 01:41:09 +0200 (CEST) Subject: [pypy-svn] r73196 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include Message-ID: <20100330234109.9E5CF282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 01:41:08 2010 New Revision: 73196 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Log: Also generate globals decls if necessary. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 01:41:08 2010 @@ -484,7 +484,7 @@ struct PyPyAPI* pypyAPI = &_pypyAPI; """ % dict(members=structmembers) - functions = generate_decls_and_callbacks(db) + functions = generate_decls_and_callbacks(db, True) global_objects = [] for name, (type, expr) in GLOBALS.iteritems(): @@ -552,7 +552,7 @@ pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros)) -def generate_decls_and_callbacks(db): +def generate_decls_and_callbacks(db, declare_globals): # implement function callbacks and generate function decls functions = [] pypy_decls = [] @@ -569,6 +569,9 @@ pypy_decls.append(header + ";") body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) + if declare_globals: + for name, (typ, expr) in GLOBALS.iteritems(): + pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name.replace("#", ""))) pypy_decl_h = udir.join('pypy_decl.h') pypy_decl_h.write('\n'.join(pypy_decls)) @@ -606,9 +609,9 @@ generate_macros(export_symbols, rename) - generate_decls_and_callbacks(db) + generate_decls_and_callbacks(db, False) - eci = build_eci(False, export_symbols) + eci = build_eci(False, export_symbols) # XXX use eci bootstrap_types(space) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Wed Mar 31 01:41:08 2010 @@ -24,10 +24,6 @@ #include "object.h" -/* move somewhere else */ -PyAPI_DATA(PyObject *) Py_None; - - #include #include #include Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/boolobject.h Wed Mar 31 01:41:08 2010 @@ -7,9 +7,6 @@ extern "C" { #endif -PyAPI_DATA(PyObject *) Py_True; -PyAPI_DATA(PyObject *) Py_False; - /* Macros for returning Py_True or Py_False, respectively */ #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 31 01:41:08 2010 @@ -383,11 +383,6 @@ #define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL -PyAPI_DATA(PyTypeObject *) PyType_Type; /* built-in 'type' */ -PyAPI_DATA(PyTypeObject *) PyBaseObject_Type; -PyAPI_DATA(PyObject *) PyExc_TypeError; -PyAPI_DATA(PyObject *) PyExc_SystemError; - /* objimpl.h ----------------------------------------------*/ #define PyObject_New(type, typeobj) \ Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/pyerrors.h Wed Mar 31 01:41:08 2010 @@ -9,8 +9,6 @@ PyObject *PyErr_NewException(char *name, PyObject *base, PyObject *dict); -PyAPI_DATA(PyObject *) PyExc_Exception; - #ifdef __cplusplus } #endif From xoraxax at codespeak.net Wed Mar 31 02:44:50 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 02:44:50 +0200 (CEST) Subject: [pypy-svn] r73197 - pypy/branch/cpython-extension/pypy/translator/c Message-ID: <20100331004450.8147E282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 02:44:48 2010 New Revision: 73197 Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py Log: Also allow a compilation info on struct instances. Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/node.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/node.py Wed Mar 31 02:44:48 2010 @@ -465,7 +465,7 @@ if USESLOTS: __slots__ = """db T obj typename implementationtypename - name ptrname + name ptrname compilation_info globalcontainer""".split() def __init__(self, db, T, obj): @@ -490,6 +490,7 @@ if self.typename != self.implementationtypename: if db.gettypedefnode(T).extra_union_for_varlength: self.name += '.b' + self.compilation_info = getattr(obj, '_compilation_info', None) self.ptrname = '(&%s)' % self.name def is_thread_local(self): From xoraxax at codespeak.net Wed Mar 31 02:45:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 02:45:20 +0200 (CEST) Subject: [pypy-svn] r73198 - in pypy/branch/cpython-extension/pypy/translator: platform tool tool/test Message-ID: <20100331004520.01DC9282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 02:45:18 2010 New Revision: 73198 Modified: pypy/branch/cpython-extension/pypy/translator/platform/posix.py pypy/branch/cpython-extension/pypy/translator/tool/cbuild.py pypy/branch/cpython-extension/pypy/translator/tool/test/test_cbuild.py Log: Support dynamic symbol lists on Linux. Modified: pypy/branch/cpython-extension/pypy/translator/platform/posix.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/platform/posix.py (original) +++ pypy/branch/cpython-extension/pypy/translator/platform/posix.py Wed Mar 31 02:45:18 2010 @@ -60,6 +60,7 @@ return [entry[2:] for entry in out.split()] def gen_makefile(self, cfiles, eci, exe_name=None, path=None): + eci = eci.convert_exportsymbols_to_file() cfiles = [py.path.local(f) for f in cfiles] cfiles += [py.path.local(f) for f in eci.separate_module_files] Modified: pypy/branch/cpython-extension/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/tool/cbuild.py (original) +++ pypy/branch/cpython-extension/pypy/translator/tool/cbuild.py Wed Mar 31 02:45:18 2010 @@ -267,6 +267,28 @@ d['separate_module_files'] += tuple(files) return ExternalCompilationInfo(**d) + def convert_exportsymbols_to_file(self): + if not self.export_symbols: + return self + num = 0 + while 1: + file_name = udir.join('dynamic-symbols-%i' % num) + num += 1 + if not file_name.check(): + break + + f = file_name.open("w") + f.write("{\n") + for sym in self.export_symbols: + f.write("%s;\n" % (sym,)) + f.write("};") + f.close() + d = self._copy_attributes() + d['link_extra'] += ("-Wl,--dynamic-list=" + str(file_name), ) + d['export_symbols'] = () + return ExternalCompilationInfo(**d) + + def get_module_files(self): d = self._copy_attributes() files = d['separate_module_files'] Modified: pypy/branch/cpython-extension/pypy/translator/tool/test/test_cbuild.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/tool/test/test_cbuild.py (original) +++ pypy/branch/cpython-extension/pypy/translator/tool/test/test_cbuild.py Wed Mar 31 02:45:18 2010 @@ -71,6 +71,17 @@ e = ExternalCompilationInfo() assert e.convert_sources_to_files() is e + def test_convert_sources_to_c_files(self): + eci = ExternalCompilationInfo( + export_symbols=("foo", ) + ) + neweci = eci.convert_exportsymbols_to_file() + le = neweci.link_extra[-1] + assert "foo;" in file(le.rsplit("=", 1)[1]).read() + e = ExternalCompilationInfo() + assert e.convert_exportsymbols_to_file() is e + + def test_make_shared_lib(self): eci = ExternalCompilationInfo( separate_module_sources = [''' From trundle at codespeak.net Wed Mar 31 03:11:16 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Wed, 31 Mar 2010 03:11:16 +0200 (CEST) Subject: [pypy-svn] r73199 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100331011116.6A184282BD8@codespeak.net> Author: trundle Date: Wed Mar 31 03:11:14 2010 New Revision: 73199 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Log: Implement PyList_Check and PyList_CheckExact. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Wed Mar 31 03:11:14 2010 @@ -2,12 +2,29 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ Py_ssize_t -from pypy.module.cpyext.api import general_check +from pypy.module.cpyext.api import general_check, general_check_exact from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.module.cpyext.macros import Py_XDECREF from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyList_Check(space, w_obj): + """Return true if p is a list object or an instance of a subtype of the list + type. + + Allowed subtypes to be accepted.""" + w_type = space.w_list + return general_check(space, w_obj, w_type) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyList_CheckExact(space, w_obj): + """Return true if p is a list object, but not an instance of a subtype of + the list type. + """ + w_type = space.w_list + return general_check_exact(space, w_obj, w_type) + @cpython_api([Py_ssize_t], PyObject) def PyList_New(space, len): """Return a new list of length len on success, or NULL on failure. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_listobject.py Wed Mar 31 03:11:14 2010 @@ -1,6 +1,25 @@ - +from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase +class TestListObject(BaseApiTest): + def test_list(self, space, api): + L = space.appexec([], """(): + class L(list): + pass + return L + """) + + l = api.PyList_New(0) + assert api.PyList_Check(l) + assert api.PyList_CheckExact(l) + + l = space.call_function(L) + assert api.PyList_Check(l) + assert not api.PyList_CheckExact(l) + + assert not api.PyList_Check(space.newtuple([])) + assert not api.PyList_CheckExact(space.newtuple([])) + class AppTestListObject(AppTestCpythonExtensionBase): def test_listobject(self): import sys From benjamin at codespeak.net Wed Mar 31 03:20:48 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 03:20:48 +0200 (CEST) Subject: [pypy-svn] r73200 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100331012048.67B49282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 03:20:46 2010 New Revision: 73200 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Log: implement PyDict_CheckExact and add tests Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 31 03:20:46 2010 @@ -1,6 +1,6 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \ - general_check, register_container + general_check, general_check_exact, register_container from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.interpreter.error import OperationError @@ -13,6 +13,11 @@ w_type = space.w_dict return general_check(space, w_obj, w_type) + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyDict_CheckExact(space, w_obj): + w_type = space.w_dict + return general_check_exact(space, w_obj, w_type) + @cpython_api([PyObject, PyObject], PyObject) def PyDict_GetItem(space, w_dict, w_key): if PyDict_Check(space, w_dict): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_dictobject.py Wed Mar 31 03:20:46 2010 @@ -21,3 +21,18 @@ assert not api.PyDict_GetItem(d, space.wrap("name")) assert api.PyErr_Occurred() is space.w_KeyError api.PyErr_Clear() + + def test_check(self, space, api): + d = api.PyDict_New() + assert api.PyDict_Check(d) + assert api.PyDict_CheckExact(d) + sub = space.appexec([], """(): + class D(dict): + pass + return D""") + d = space.call_function(sub) + assert api.PyDict_Check(d) + assert not api.PyDict_CheckExact(d) + i = space.wrap(2) + assert not api.PyDict_Check(i) + assert not api.PyDict_CheckExact(i) From trundle at codespeak.net Wed Mar 31 04:01:44 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Wed, 31 Mar 2010 04:01:44 +0200 (CEST) Subject: [pypy-svn] r73201 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100331020144.A26AD282BD8@codespeak.net> Author: trundle Date: Wed Mar 31 04:01:43 2010 New Revision: 73201 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Log: Implement PyErr_SetObject. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 31 04:01:43 2010 @@ -4,11 +4,17 @@ register_container, CANNOT_FAIL from pypy.module.cpyext.state import State + at cpython_api([PyObject, PyObject], lltype.Void) +def PyErr_SetObject(space, w_type, w_value): + """This function is similar to PyErr_SetString() but lets you specify an + arbitrary Python object for the "value" of the exception.""" + state = space.fromcache(State) + state.set_exception(w_type, w_value) + @cpython_api([PyObject, rffi.CCHARP], lltype.Void) def PyErr_SetString(space, w_type, message_ptr): message = rffi.charp2str(message_ptr) - state = space.fromcache(State) - state.set_exception(w_type, space.wrap(message)) + PyErr_SetObject(space, w_type, space.wrap(message)) @cpython_api([], PyObject, borrowed=True) def PyErr_Occurred(space): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Wed Mar 31 04:01:43 2010 @@ -1560,12 +1560,6 @@ exception state.""" raise NotImplementedError - at cpython_api([PyObject, PyObject], lltype.Void) -def PyErr_SetObject(space, type, value): - """This function is similar to PyErr_SetString() but lets you specify an - arbitrary Python object for the "value" of the exception.""" - raise NotImplementedError - @cpython_api([PyObject, rffi.CCHARP, ...], PyObject) def PyErr_Format(space, exception, format, ): """This function sets the error indicator and returns NULL. exception should be Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Wed Mar 31 04:01:43 2010 @@ -1,3 +1,4 @@ +from pypy.module.cpyext.state import State from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.rpython.lltypesystem import rffi @@ -35,6 +36,14 @@ api.PyErr_Clear() + def test_SetObject(self, space, api): + api.PyErr_SetObject(space.w_ValueError, space.wrap("a value")) + assert api.PyErr_Occurred() is space.w_ValueError + state = space.fromcache(State) + assert space.eq_w(state.exc_value, space.wrap("a value")) + + api.PyErr_Clear() + class AppTestFetch(AppTestCpythonExtensionBase): def test_occurred(self): module = self.import_extension('foo', [ From benjamin at codespeak.net Wed Mar 31 04:11:38 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 04:11:38 +0200 (CEST) Subject: [pypy-svn] r73202 - pypy/trunk/pypy/tool Message-ID: <20100331021138.5A7F8282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 04:11:36 2010 New Revision: 73202 Modified: pypy/trunk/pypy/tool/runsubprocess.py Log: pass correct filter arguments Modified: pypy/trunk/pypy/tool/runsubprocess.py ============================================================================== --- pypy/trunk/pypy/tool/runsubprocess.py (original) +++ pypy/trunk/pypy/tool/runsubprocess.py Wed Mar 31 04:11:36 2010 @@ -47,8 +47,8 @@ _source = os.path.dirname(os.path.abspath(__file__)) _source = os.path.join(_source, 'runsubprocess.py') # and not e.g. '.pyc' # Let's not hear about os.popen2's deprecation. - warnings.filterwarnings("ignore", "popen2", DeprecationWarning, - "runsubprocess") + warnings.filterwarnings("ignore", ".*popen2.*", DeprecationWarning, + "pypy.tool.runsubprocess") _child_stdin, _child_stdout = os.popen2( "'%s' '%s'" % (sys.executable, _source)) From trundle at codespeak.net Wed Mar 31 04:15:10 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Wed, 31 Mar 2010 04:15:10 +0200 (CEST) Subject: [pypy-svn] r73203 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100331021510.38C6F282BD8@codespeak.net> Author: trundle Date: Wed Mar 31 04:15:08 2010 New Revision: 73203 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Log: Implement PyErr_ExceptionMatches. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 31 04:15:08 2010 @@ -43,3 +43,11 @@ else: w_given_type = w_given return space.exception_match(w_given_type, w_exc) + + at cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) +def PyErr_ExceptionMatches(space, w_exc): + """Equivalent to PyErr_GivenExceptionMatches(PyErr_Occurred(), exc). This + should only be called when an exception is actually set; a memory access + violation will occur if no exception has been raised.""" + w_type = PyErr_Occurred(space) + return PyErr_GivenExceptionMatches(space, w_type, w_exc) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stubs.py Wed Mar 31 04:15:08 2010 @@ -1516,13 +1516,6 @@ """Alias for PyErr_PrintEx(1).""" raise NotImplementedError - at cpython_api([PyObject], rffi.INT_real) -def PyErr_ExceptionMatches(space, exc): - """Equivalent to PyErr_GivenExceptionMatches(PyErr_Occurred(), exc). This - should only be called when an exception is actually set; a memory access - violation will occur if no exception has been raised.""" - raise NotImplementedError - @cpython_api([{PyObject**exc}, {PyObject**val}, {PyObject**tb}], lltype.Void) def PyErr_NormalizeException(space, , , ): """Under certain circumstances, the values returned by PyErr_Fetch() below Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_pyerrors.py Wed Mar 31 04:15:08 2010 @@ -27,6 +27,14 @@ exceptions = space.newtuple([space.w_LookupError, space.w_ValueError]) assert exc_matches(space.w_ValueError, exceptions) + def test_ExceptionMatches(self, space, api): + api.PyErr_SetObject(space.w_ValueError, space.wrap("message")) + assert api.PyErr_ExceptionMatches(space.w_Exception) + assert api.PyErr_ExceptionMatches(space.w_ValueError) + assert not api.PyErr_ExceptionMatches(space.w_TypeError) + + api.PyErr_Clear() + def test_Occurred(self, space, api): assert not api.PyErr_Occurred() string = rffi.str2charp("spam and eggs") From fijall at gmail.com Wed Mar 31 06:01:17 2010 From: fijall at gmail.com (Maciej Fijalkowski) Date: Tue, 30 Mar 2010 22:01:17 -0600 Subject: [pypy-svn] r73188 - pypy/benchmarks In-Reply-To: <20100330171024.D77CC282B9D@codespeak.net> References: <20100330171024.D77CC282B9D@codespeak.net> Message-ID: > + ? ?if branch == "": > + ? ? ? ?print("ERROR: No branch defined") > + ? ? ? ?return 1 > This is a good way to make sure that nobody ever reads this message. How about an exception instead? From fijal at codespeak.net Wed Mar 31 07:00:06 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 31 Mar 2010 07:00:06 +0200 (CEST) Subject: [pypy-svn] r73204 - in pypy/trunk/pypy/interpreter: . test Message-ID: <20100331050006.4A135282BD8@codespeak.net> Author: fijal Date: Wed Mar 31 07:00:02 2010 New Revision: 73204 Modified: pypy/trunk/pypy/interpreter/function.py pypy/trunk/pypy/interpreter/test/test_function.py Log: Handle *somehow* the case of passing wrong args to function.__setstate__. At the very least don't explode with RPython ValueError Modified: pypy/trunk/pypy/interpreter/function.py ============================================================================== --- pypy/trunk/pypy/interpreter/function.py (original) +++ pypy/trunk/pypy/interpreter/function.py Wed Mar 31 07:00:02 2010 @@ -295,8 +295,13 @@ def descr_function__setstate__(self, space, w_args): from pypy.interpreter.pycode import PyCode args_w = space.unpackiterable(w_args) - (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs_w, - w_func_dict, w_module) = args_w + try: + (w_name, w_doc, w_code, w_func_globals, w_closure, w_defs_w, + w_func_dict, w_module) = args_w + except ValueError: + # wrong args + raise OperationError(space.w_ValueError, + space.wrap("Wrong arguments to function.__setstate__")) self.space = space self.name = space.str_w(w_name) 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 Mar 31 07:00:02 2010 @@ -288,6 +288,11 @@ f = lambda: 42 assert f.func_doc is None + def test_setstate_called_with_wrong_args(self): + f = lambda: 42 + # not sure what it should raise, since CPython doesn't have setstate + # on function types + raises(ValueError, type(f).__setstate__, f, (1, 2, 3)) class AppTestMethod: def test_simple_call(self): From afa at codespeak.net Wed Mar 31 14:10:46 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 31 Mar 2010 14:10:46 +0200 (CEST) Subject: [pypy-svn] r73206 - in pypy/branch/cpython-extension/pypy/module/cpyext: . test Message-ID: <20100331121046.445EE282BDB@codespeak.net> Author: afa Date: Wed Mar 31 14:10:43 2010 New Revision: 73206 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Log: Treats the "implicit-function-declaration" warning as an error on win32 as well Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 14:10:43 2010 @@ -582,7 +582,10 @@ kwds = {} export_symbols_eci = export_symbols[:] - if sys.platform != "win32": + if sys.platform == "win32": + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + else: kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] if build_bridge: Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 31 14:10:43 2010 @@ -74,6 +74,8 @@ api_library = state.api_lib if sys.platform == 'win32': kwds["libraries"] = [api_library] + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] else: kwds["link_files"] = [str(api_library + '.so')] kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] From trundle at codespeak.net Wed Mar 31 14:17:22 2010 From: trundle at codespeak.net (trundle at codespeak.net) Date: Wed, 31 Mar 2010 14:17:22 +0200 (CEST) Subject: [pypy-svn] r73207 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100331121722.DD202282BD8@codespeak.net> Author: trundle Date: Wed Mar 31 14:17:21 2010 New Revision: 73207 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Log: typo Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 31 14:17:21 2010 @@ -7,7 +7,7 @@ /* -CPyton has this for backwards compatibility with really old extensions, and now +CPython has this for backwards compatibility with really old extensions, and now we have it for compatibility with CPython. */ #define staticforward static From afa at codespeak.net Wed Mar 31 14:33:28 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 31 Mar 2010 14:33:28 +0200 (CEST) Subject: [pypy-svn] r73208 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test Message-ID: <20100331123328.7720A282BD8@codespeak.net> Author: afa Date: Wed Mar 31 14:33:26 2010 New Revision: 73208 Added: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py - copied, changed from r73205, pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Removed: pypy/branch/cpython-extension/pypy/module/cpyext/macros.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/api.py pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py pypy/branch/cpython-extension/pypy/module/cpyext/object.py pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py Log: - Move object&memory management into a new file pyobject.py - rename Py_INCREF to Py_IncRef (the old name is still available from C) --Cette ligne, et les suivantes ci-dessous, seront ignor?es-- M cpyext/test/test_borrow.py M cpyext/test/test_cpyext.py M cpyext/include/object.h M cpyext/stringobject.py M cpyext/__init__.py M cpyext/listobject.py M cpyext/object.py M cpyext/methodobject.py M cpyext/sequence.py M cpyext/typeobject.py M cpyext/api.py M cpyext/dictobject.py M cpyext/typeobjectdefs.py M cpyext/modsupport.py A + cpyext/pyobject.py M cpyext/state.py M cpyext/tupleobject.py D cpyext/macros.py M cpyext/pyerrors.py Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Wed Mar 31 14:33:26 2010 @@ -28,11 +28,11 @@ space.wrap(state.api_lib)) # import these modules to register api functions by side-effect +import pypy.module.cpyext.pyobject import pypy.module.cpyext.boolobject import pypy.module.cpyext.floatobject import pypy.module.cpyext.modsupport import pypy.module.cpyext.pythonrun -import pypy.module.cpyext.macros import pypy.module.cpyext.pyerrors import pypy.module.cpyext.typeobject import pypy.module.cpyext.object Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 14:33:26 2010 @@ -25,7 +25,6 @@ # CPython 2.4 compatibility from py.builtin import BaseException -DEBUG_REFCOUNT = False DEBUG_WRAPPER = False Py_ssize_t = lltype.Signed @@ -139,6 +138,8 @@ @specialize.ll() def unwrapper(space, *args): + from pypy.module.cpyext.pyobject import Py_DecRef + from pypy.module.cpyext.pyobject import make_ref, from_ref newargs = () to_decref = [] for i, (ARG, is_wrapped) in types_names_enum_ui: @@ -177,9 +178,8 @@ if api_function.borrowed: state = space.fromcache(State) state.last_container = 0 - from pypy.module.cpyext.macros import Py_DECREF for arg in to_decref: - Py_DECREF(space, arg) + Py_DecRef(space, arg) unwrapper.func = func unwrapper.api_func = api_function unwrapper._always_inline_ = True @@ -241,136 +241,6 @@ TYPES[name].become(TYPE) -class NullPointerException(Exception): - pass - -class InvalidPointerException(Exception): - pass - -def debug_refcount(*args, **kwargs): - frame_stackdepth = kwargs.pop("frame_stackdepth", 2) - assert not kwargs - frame = sys._getframe(frame_stackdepth) - print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), - for arg in args: - print >>sys.stderr, arg, - print >>sys.stderr - - -def make_ref(space, w_obj, borrowed=False, steal=False): - from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF - if w_obj is None: - return lltype.nullptr(PyObject.TO) - assert isinstance(w_obj, W_Root) - state = space.fromcache(State) - py_obj = state.py_objects_w2r.get(w_obj, lltype.nullptr(PyObject.TO)) - if not py_obj: - from pypy.module.cpyext.typeobject import allocate_type_obj,\ - W_PyCTypeObject, W_PyCObject - w_type = space.type(w_obj) - if space.is_w(w_type, space.w_type): - pto = allocate_type_obj(space, w_obj) - py_obj = rffi.cast(PyObject, pto) - # c_ob_type and c_ob_refcnt are set by allocate_type_obj - elif isinstance(w_obj, W_PyCObject): - w_type = space.type(w_obj) - assert isinstance(w_type, W_PyCTypeObject) - pto = w_type.pto - # Don't increase refcount for non-heaptypes - # Py_INCREF(space, pto) - basicsize = pto.c_tp_basicsize - py_obj_pad = lltype.malloc(rffi.VOIDP.TO, basicsize, - flavor="raw", zero=True) - py_obj = rffi.cast(PyObject, py_obj_pad) - py_obj.c_ob_refcnt = 1 - py_obj.c_ob_type = rffi.cast(PyObject, pto) - elif isinstance(w_obj, W_StringObject): - py_obj_str = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True) - py_obj_str.c_size = len(space.str_w(w_obj)) - py_obj_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO) - pto = make_ref(space, space.w_str) - py_obj = rffi.cast(PyObject, py_obj_str) - py_obj.c_ob_refcnt = 1 - py_obj.c_ob_type = rffi.cast(PyObject, pto) - else: - py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True) - py_obj.c_ob_refcnt = 1 - pto = make_ref(space, space.type(w_obj)) - py_obj.c_ob_type = rffi.cast(PyObject, pto) - ptr = rffi.cast(ADDR, py_obj) - if DEBUG_REFCOUNT: - debug_refcount("MAKREF", py_obj, w_obj) - state.py_objects_w2r[w_obj] = py_obj - state.py_objects_r2w[ptr] = w_obj - if borrowed and ptr not in state.borrowed_objects: - state.borrowed_objects[ptr] = None - elif not steal: - if borrowed: - py_obj_addr = rffi.cast(ADDR, py_obj) - if py_obj_addr not in state.borrowed_objects: - Py_INCREF(space, py_obj) - state.borrowed_objects[py_obj_addr] = None - else: - Py_INCREF(space, py_obj) - return py_obj - -def force_string(space, ref): - state = space.fromcache(State) - ref = rffi.cast(PyStringObject, ref) - s = rffi.charpsize2str(ref.c_buffer, ref.c_size) - ref = rffi.cast(PyObject, ref) - w_str = space.wrap(s) - state.py_objects_w2r[w_str] = ref - ptr = rffi.cast(ADDR, ref) - state.py_objects_r2w[ptr] = w_str - return w_str - - -def from_ref(space, ref): - assert lltype.typeOf(ref) == PyObject - if not ref: - return None - state = space.fromcache(State) - ptr = rffi.cast(ADDR, ref) - try: - obj = state.py_objects_r2w[ptr] - except KeyError: - ref_type = ref.c_ob_type - if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str): - return force_string(space, ref) - else: - msg = "" - if not we_are_translated(): - msg = "Got invalid reference to a PyObject: %r" % (ref, ) - raise InvalidPointerException(msg) - return obj - - - at cpython_api([PyObject], lltype.Void, external=False) -def register_container(space, container): - state = space.fromcache(State) - if not container: # self-managed - container_ptr = -1 - else: - container_ptr = rffi.cast(ADDR, container) - assert not state.last_container, "Last container was not fetched" - state.last_container = container_ptr - -def add_borrowed_object(space, obj): - state = space.fromcache(State) - container_ptr = state.last_container - state.last_container = 0 - if not container_ptr: - raise NullPointerException - if container_ptr == -1: - return - borrowees = state.borrow_mapping.get(container_ptr, None) - if borrowees is None: - state.borrow_mapping[container_ptr] = borrowees = {} - obj_ptr = rffi.cast(ADDR, obj) - borrowees[obj_ptr] = None - - def general_check(space, w_obj, w_type): w_obj_type = space.type(w_obj) return int(space.is_w(w_obj_type, w_type) or space.is_true(space.issubtype(w_obj_type, w_type))) @@ -387,6 +257,9 @@ @specialize.ll() def wrapper(*args): + from pypy.module.cpyext.pyobject import make_ref, from_ref + from pypy.module.cpyext.pyobject import add_borrowed_object + from pypy.module.cpyext.pyobject import NullPointerException boxed_args = () if DEBUG_WRAPPER: print >>sys.stderr, callable, @@ -445,6 +318,7 @@ return wrapper def bootstrap_types(space): + from pypy.module.cpyext.pyobject import make_ref from pypy.module.cpyext.typeobject import PyTypeObjectPtr, PyPyType_Ready # bootstrap this damn cycle type_pto = make_ref(space, space.w_type) @@ -464,6 +338,8 @@ # back into Pypy space functions # Do not call this more than once per process def build_bridge(space, rename=True): + from pypy.module.cpyext.pyobject import make_ref + export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) db = LowLevelDatabase() @@ -607,6 +483,8 @@ def setup_library(space, rename=False): + from pypy.module.cpyext.pyobject import make_ref + export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) db = LowLevelDatabase() @@ -665,7 +543,7 @@ @specialize.memo() def make_generic_cpy_call(FT, decref_args): - from pypy.module.cpyext.macros import Py_DECREF + from pypy.module.cpyext.pyobject import make_ref, from_ref, Py_DecRef from pypy.module.cpyext.pyerrors import PyErr_Occurred unrolling_arg_types = unrolling_iterable(enumerate(FT.ARGS)) RESULT_TYPE = FT.RESULT @@ -701,7 +579,7 @@ # that is called from Python must be an owned reference # - ownership is transferred from the function to its caller. if result: - Py_DECREF(space, result) + Py_DecRef(space, result) # Check for exception consistency has_error = PyErr_Occurred(space) is not None @@ -721,6 +599,6 @@ finally: if decref_args: for ref in to_decref: - Py_DECREF(space, ref) + Py_DecRef(space, ref) return generic_cpy_call Modified: pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/dictobject.py Wed Mar 31 14:33:26 2010 @@ -1,6 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL, \ - general_check, general_check_exact, register_container +from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL +from pypy.module.cpyext.api import general_check, general_check_exact +from pypy.module.cpyext.pyobject import PyObject, register_container from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.interpreter.error import OperationError Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/object.h Wed Mar 31 14:33:26 2010 @@ -37,6 +37,9 @@ PyObject_VAR_HEAD } PyVarObject; +#define Py_INCREF(ob) (Py_IncRef(ob)) +#define Py_DECREF(ob) (Py_DecRef(ob)) + #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/listobject.py Wed Mar 31 14:33:26 2010 @@ -1,10 +1,9 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ - Py_ssize_t +from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t from pypy.module.cpyext.api import general_check, general_check_exact from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall -from pypy.module.cpyext.macros import Py_XDECREF +from pypy.module.cpyext.pyobject import Py_DecRef, PyObject from pypy.objspace.std.listobject import W_ListObject from pypy.interpreter.error import OperationError @@ -44,7 +43,7 @@ This function "steals" a reference to item and discards a reference to an item already in the list at the affected position. """ - Py_XDECREF(space, w_item) + Py_DecRef(space, w_item) if not isinstance(w_list, W_ListObject): PyErr_BadInternalCall(space) wrappeditems = w_list.wrappeditems Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py Wed Mar 31 14:33:26 2010 @@ -7,8 +7,8 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.function import BuiltinFunction, Method from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import PyObject, from_ref, \ - make_ref, generic_cpy_call +from pypy.module.cpyext.pyobject import PyObject, from_ref, make_ref +from pypy.module.cpyext.api import generic_cpy_call from pypy.module.cpyext.state import State from pypy.module.cpyext.pyerrors import PyErr_Occurred from pypy.rlib.objectmodel import we_are_translated Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py Wed Mar 31 14:33:26 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, cpython_struct, PyObject, \ - METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL, \ - register_container +from pypy.module.cpyext.api import cpython_api, cpython_struct, \ + METH_STATIC, METH_CLASS, METH_COEXIST, general_check, CANNOT_FAIL +from pypy.module.cpyext.pyobject import PyObject, register_container from pypy.interpreter.module import Module from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall Modified: pypy/branch/cpython-extension/pypy/module/cpyext/object.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/object.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/object.py Wed Mar 31 14:33:26 2010 @@ -1,8 +1,8 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ - generic_cpy_call, CANNOT_FAIL +from pypy.module.cpyext.api import cpython_api, generic_cpy_call, CANNOT_FAIL +from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref +from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef from pypy.module.cpyext.state import State -from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF from pypy.module.cpyext.typeobject import PyTypeObjectPtr, W_PyCTypeObject, W_PyCObject from pypy.objspace.std.objectobject import W_ObjectObject import pypy.module.__builtin__.operation as operation Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Wed Mar 31 14:33:26 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.interpreter.error import OperationError -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref,\ - register_container, CANNOT_FAIL +from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL +from pypy.module.cpyext.pyobject import PyObject, make_ref, register_container from pypy.module.cpyext.state import State @cpython_api([PyObject, PyObject], lltype.Void) Copied: pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py (from r73205, pypy/branch/cpython-extension/pypy/module/cpyext/macros.py) ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/macros.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/pyobject.py Wed Mar 31 14:33:26 2010 @@ -1,14 +1,127 @@ import sys +from pypy.interpreter.baseobjspace import W_Root from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, make_ref, from_ref, \ - ADDR, debug_refcount, DEBUG_REFCOUNT +from pypy.module.cpyext.api import cpython_api, PyObject, PyStringObject, ADDR from pypy.module.cpyext.state import State +from pypy.objspace.std.stringobject import W_StringObject +from pypy.rlib.objectmodel import we_are_translated + +#________________________________________________________ +# refcounted object support + +class NullPointerException(Exception): + pass + +class InvalidPointerException(Exception): + pass + +DEBUG_REFCOUNT = False + +def debug_refcount(*args, **kwargs): + frame_stackdepth = kwargs.pop("frame_stackdepth", 2) + assert not kwargs + frame = sys._getframe(frame_stackdepth) + print >>sys.stderr, "%25s" % (frame.f_code.co_name, ), + for arg in args: + print >>sys.stderr, arg, + print >>sys.stderr + + +def make_ref(space, w_obj, borrowed=False, steal=False): + if w_obj is None: + return lltype.nullptr(PyObject.TO) + assert isinstance(w_obj, W_Root) + state = space.fromcache(State) + py_obj = state.py_objects_w2r.get(w_obj, lltype.nullptr(PyObject.TO)) + if not py_obj: + from pypy.module.cpyext.typeobject import allocate_type_obj,\ + W_PyCTypeObject, W_PyCObject + w_type = space.type(w_obj) + if space.is_w(w_type, space.w_type): + pto = allocate_type_obj(space, w_obj) + py_obj = rffi.cast(PyObject, pto) + # c_ob_type and c_ob_refcnt are set by allocate_type_obj + elif isinstance(w_obj, W_PyCObject): + w_type = space.type(w_obj) + assert isinstance(w_type, W_PyCTypeObject) + pto = w_type.pto + # Don't increase refcount for non-heaptypes + # Py_IncRef(space, pto) + basicsize = pto.c_tp_basicsize + py_obj_pad = lltype.malloc(rffi.VOIDP.TO, basicsize, + flavor="raw", zero=True) + py_obj = rffi.cast(PyObject, py_obj_pad) + py_obj.c_ob_refcnt = 1 + py_obj.c_ob_type = rffi.cast(PyObject, pto) + elif isinstance(w_obj, W_StringObject): + py_obj_str = lltype.malloc(PyStringObject.TO, flavor='raw', zero=True) + py_obj_str.c_size = len(space.str_w(w_obj)) + py_obj_str.c_buffer = lltype.nullptr(rffi.CCHARP.TO) + pto = make_ref(space, space.w_str) + py_obj = rffi.cast(PyObject, py_obj_str) + py_obj.c_ob_refcnt = 1 + py_obj.c_ob_type = rffi.cast(PyObject, pto) + else: + py_obj = lltype.malloc(PyObject.TO, flavor="raw", zero=True) + py_obj.c_ob_refcnt = 1 + pto = make_ref(space, space.type(w_obj)) + py_obj.c_ob_type = rffi.cast(PyObject, pto) + ptr = rffi.cast(ADDR, py_obj) + if DEBUG_REFCOUNT: + debug_refcount("MAKREF", py_obj, w_obj) + state.py_objects_w2r[w_obj] = py_obj + state.py_objects_r2w[ptr] = w_obj + if borrowed and ptr not in state.borrowed_objects: + state.borrowed_objects[ptr] = None + elif not steal: + if borrowed: + py_obj_addr = rffi.cast(ADDR, py_obj) + if py_obj_addr not in state.borrowed_objects: + Py_IncRef(space, py_obj) + state.borrowed_objects[py_obj_addr] = None + else: + Py_IncRef(space, py_obj) + return py_obj + +def force_string(space, ref): + state = space.fromcache(State) + ref = rffi.cast(PyStringObject, ref) + s = rffi.charpsize2str(ref.c_buffer, ref.c_size) + ref = rffi.cast(PyObject, ref) + w_str = space.wrap(s) + state.py_objects_w2r[w_str] = ref + ptr = rffi.cast(ADDR, ref) + state.py_objects_r2w[ptr] = w_str + return w_str + + +def from_ref(space, ref): + assert lltype.typeOf(ref) == PyObject + if not ref: + return None + state = space.fromcache(State) + ptr = rffi.cast(ADDR, ref) + try: + obj = state.py_objects_r2w[ptr] + except KeyError: + ref_type = ref.c_ob_type + if ref != ref_type and space.is_w(from_ref(space, ref_type), space.w_str): + return force_string(space, ref) + else: + msg = "" + if not we_are_translated(): + msg = "Got invalid reference to a PyObject: %r" % (ref, ) + raise InvalidPointerException(msg) + return obj # XXX Optimize these functions and put them into macro definitions @cpython_api([PyObject], lltype.Void) -def Py_DECREF(space, obj): +def Py_DecRef(space, obj): + if not obj: + return + from pypy.module.cpyext.typeobject import string_dealloc obj.c_ob_refcnt -= 1 if DEBUG_REFCOUNT: @@ -31,7 +144,7 @@ w_containee = state.py_objects_r2w.get(containee, None) if w_containee is not None: containee = state.py_objects_w2r[w_containee] - Py_DECREF(space, w_containee) + Py_DecRef(space, w_containee) containee_ptr = rffi.cast(ADDR, containee) try: del state.borrowed_objects[containee_ptr] @@ -46,22 +159,14 @@ assert obj.c_ob_refcnt > 0 @cpython_api([PyObject], lltype.Void) -def Py_INCREF(space, obj): +def Py_IncRef(space, obj): + if not obj: + return obj.c_ob_refcnt += 1 assert obj.c_ob_refcnt > 0 if DEBUG_REFCOUNT: debug_refcount("INCREF", obj, obj.c_ob_refcnt, frame_stackdepth=3) - at cpython_api([PyObject], lltype.Void) -def Py_XINCREF(space, obj): - if obj: - Py_INCREF(space, obj) - - at cpython_api([PyObject], lltype.Void) -def Py_XDECREF(space, obj): - if obj: - Py_DECREF(space, obj) - def _Py_Dealloc(space, obj): from pypy.module.cpyext.typeobject import PyTypeObjectPtr from pypy.module.cpyext.api import generic_cpy_call_dont_decref @@ -71,3 +176,31 @@ # "'s type which is", rffi.charp2str(pto.c_tp_name) generic_cpy_call_dont_decref(space, pto.c_tp_dealloc, obj) +#___________________________________________________________ +# Support for borrowed references + + at cpython_api([PyObject], lltype.Void, external=False) +def register_container(space, container): + state = space.fromcache(State) + if not container: # self-managed + container_ptr = -1 + else: + container_ptr = rffi.cast(ADDR, container) + assert not state.last_container, "Last container was not fetched" + state.last_container = container_ptr + +def add_borrowed_object(space, obj): + state = space.fromcache(State) + container_ptr = state.last_container + state.last_container = 0 + if not container_ptr: + raise NullPointerException + if container_ptr == -1: + return + borrowees = state.borrow_mapping.get(container_ptr, None) + if borrowees is None: + state.borrow_mapping[container_ptr] = borrowees = {} + obj_ptr = rffi.cast(ADDR, obj) + borrowees[obj_ptr] = None + + Modified: pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/sequence.py Wed Mar 31 14:33:26 2010 @@ -1,7 +1,7 @@ from pypy.interpreter.error import OperationError -from pypy.module.cpyext.api import cpython_api, PyObject, CANNOT_FAIL,\ - Py_ssize_t, register_container +from pypy.module.cpyext.api import cpython_api, CANNOT_FAIL, Py_ssize_t +from pypy.module.cpyext.pyobject import PyObject, register_container from pypy.rpython.lltypesystem import rffi, lltype from pypy.objspace.std import listobject, tupleobject Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Wed Mar 31 14:33:26 2010 @@ -26,13 +26,13 @@ self.exc_value = w_value def clear_exception(self): - from pypy.module.cpyext.macros import Py_DECREF - from pypy.module.cpyext.api import make_ref, ADDR + from pypy.module.cpyext.pyobject import Py_DecRef, make_ref + from pypy.module.cpyext.api import ADDR # handling of borrowed objects, remove when we have # a weakkeydict exc_type = make_ref(self.space, self.exc_type, borrowed=True) if exc_type: - Py_DECREF(self.space, exc_type) + Py_DecRef(self.space, exc_type) containee_ptr = rffi.cast(ADDR, exc_type) del self.borrowed_objects[containee_ptr] self.exc_type = None Modified: pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/stringobject.py Wed Mar 31 14:33:26 2010 @@ -1,7 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, PyVarObjectFields, \ - PyStringObject, Py_ssize_t, cpython_struct, make_ref, from_ref, CANNOT_FAIL, \ - general_check +from pypy.module.cpyext.api import cpython_api, PyVarObjectFields, \ + PyStringObject, Py_ssize_t, cpython_struct, CANNOT_FAIL, general_check +from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref @cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_borrow.py Wed Mar 31 14:33:26 2010 @@ -2,7 +2,7 @@ from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.state import State -from pypy.module.cpyext.api import make_ref, add_borrowed_object +from pypy.module.cpyext.pyobject import make_ref, add_borrowed_object class TestBorrowing(BaseApiTest): @@ -10,14 +10,14 @@ state = space.fromcache(State) w_int = space.wrap(1) w_tuple = space.newtuple([w_int]) - api.Py_INCREF(w_tuple) + api.Py_IncRef(w_tuple) api.register_container(w_tuple) one_pyo = make_ref(space, w_int, borrowed=True) add_borrowed_object(space, one_pyo) print state.borrowed_objects - api.Py_DECREF(w_tuple) + api.Py_DecRef(w_tuple) state.print_refcounts() - py.test.raises(AssertionError, api.Py_DECREF, one_pyo) + py.test.raises(AssertionError, api.Py_DecRef, one_pyo) class AppTestStringObject(AppTestCpythonExtensionBase): def test_tuple_borrowing(self): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py Wed Mar 31 14:33:26 2010 @@ -9,7 +9,7 @@ from pypy.translator import platform from pypy.module.cpyext import api from pypy.module.cpyext.state import State -from pypy.module.cpyext.macros import Py_DECREF +from pypy.module.cpyext.pyobject import Py_DecRef, InvalidPointerException from pypy.translator.goal import autopath from pypy.lib.identity_dict import identity_dict @@ -123,10 +123,10 @@ self.space.wrap('foo')) self.space.delitem(self.space.sys.get('modules'), self.space.wrap('foo')) - Py_DECREF(self.space, w_mod) + Py_DecRef(self.space, w_mod) state = self.space.fromcache(State) for w_obj in state.non_heaptypes: - Py_DECREF(self.space, w_obj) + Py_DecRef(self.space, w_obj) except OperationError: pass state = self.space.fromcache(State) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/tupleobject.py Wed Mar 31 14:33:26 2010 @@ -1,8 +1,7 @@ from pypy.rpython.lltypesystem import rffi, lltype -from pypy.module.cpyext.api import cpython_api, PyObject, Py_ssize_t, \ - general_check, CANNOT_FAIL, register_container, \ - general_check_exact -from pypy.module.cpyext.macros import Py_DECREF +from pypy.module.cpyext.api import cpython_api, Py_ssize_t, \ + general_check, CANNOT_FAIL, general_check_exact +from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, register_container from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall from pypy.objspace.std.tupleobject import W_TupleObject @@ -27,7 +26,7 @@ PyErr_BadInternalCall(space) assert isinstance(w_t, W_TupleObject) w_t.wrappeditems[pos] = w_obj - Py_DECREF(space, w_obj) # SetItem steals a reference! + Py_DecRef(space, w_obj) # SetItem steals a reference! return 0 @cpython_api([PyObject, Py_ssize_t], PyObject, borrowed=True) Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobject.py Wed Mar 31 14:33:26 2010 @@ -10,14 +10,14 @@ from pypy.objspace.std.objectobject import W_ObjectObject from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ - PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ - Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ - PyStringObject, ADDR, from_ref, generic_cpy_call + PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, generic_cpy_call, \ + Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, PyStringObject, ADDR +from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref from pypy.interpreter.module import Module from pypy.module.cpyext.modsupport import convert_method_defs from pypy.module.cpyext.state import State from pypy.module.cpyext.methodobject import PyDescr_NewWrapper -from pypy.module.cpyext.macros import Py_INCREF, Py_DECREF, Py_XDECREF +from pypy.module.cpyext.pyobject import Py_IncRef, Py_DecRef from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr, PyTypeObject, \ PyGetSetDef from pypy.module.cpyext.slotdefs import slotdefs @@ -129,7 +129,7 @@ # XXX call tp_del if necessary generic_cpy_call(space, dealloc, obj) pto = rffi.cast(PyObject, pto) - Py_DECREF(space, pto) + Py_DecRef(space, pto) @cpython_api([PyObject], lltype.Void, external=False) @@ -141,7 +141,7 @@ obj_voidp = rffi.cast(rffi.VOIDP_real, obj) generic_cpy_call(space, pto.c_tp_free, obj_voidp) pto = rffi.cast(PyObject, pto) - Py_DECREF(space, pto) + Py_DecRef(space, pto) @cpython_api([PyObject], lltype.Void, external=False) def type_dealloc(space, obj): @@ -149,15 +149,15 @@ obj_pto = rffi.cast(PyTypeObjectPtr, obj) type_pto = rffi.cast(PyTypeObjectPtr, obj.c_ob_type) base_pyo = rffi.cast(PyObject, obj_pto.c_tp_base) - Py_XDECREF(space, base_pyo) - Py_XDECREF(space, obj_pto.c_tp_bases) - Py_XDECREF(space, obj_pto.c_tp_cache) # lets do it like cpython + Py_DecRef(space, base_pyo) + Py_DecRef(space, obj_pto.c_tp_bases) + Py_DecRef(space, obj_pto.c_tp_cache) # lets do it like cpython if obj_pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: lltype.free(obj_pto.c_tp_name, flavor="raw") obj_pto_voidp = rffi.cast(rffi.VOIDP_real, obj_pto) generic_cpy_call(space, type_pto.c_tp_free, obj_pto_voidp) pto = rffi.cast(PyObject, type_pto) - Py_DECREF(space, pto) + Py_DecRef(space, pto) def allocate_type_obj(space, w_type): Modified: pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/typeobjectdefs.py Wed Mar 31 14:33:26 2010 @@ -1,9 +1,9 @@ from pypy.rpython.lltypesystem import rffi, lltype from pypy.rpython.lltypesystem.lltype import Ptr, FuncType, Void from pypy.module.cpyext.api import cpython_api, cpython_api_c, cpython_struct, \ - PyObject, PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ - Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, make_ref, \ - PyStringObject, ADDR, from_ref + PyVarObjectFields, Py_ssize_t, Py_TPFLAGS_READYING, \ + Py_TPFLAGS_READY, Py_TPFLAGS_HEAPTYPE, PyStringObject, ADDR +from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref from pypy.module.cpyext.modsupport import PyMethodDef From afa at codespeak.net Wed Mar 31 14:38:30 2010 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 31 Mar 2010 14:38:30 +0200 (CEST) Subject: [pypy-svn] r73209 - pypy/trunk/pypy/translator/platform Message-ID: <20100331123830.D7967282BD8@codespeak.net> Author: afa Date: Wed Mar 31 14:38:29 2010 New Revision: 73209 Modified: pypy/trunk/pypy/translator/platform/__init__.py pypy/trunk/pypy/translator/platform/maemo.py pypy/trunk/pypy/translator/platform/posix.py pypy/trunk/pypy/translator/platform/windows.py Log: Now that CPython headers are no more needed, remove the "PC" include directory on windows. Modified: pypy/trunk/pypy/translator/platform/__init__.py ============================================================================== --- pypy/trunk/pypy/translator/platform/__init__.py (original) +++ pypy/trunk/pypy/translator/platform/__init__.py Wed Mar 31 14:38:29 2010 @@ -114,9 +114,12 @@ for line in stderr.splitlines(): log.WARNING(line) - + def _preprocess_include_dirs(self, include_dirs): + # hook for maemo + return include_dirs + def _compile_args_from_eci(self, eci, standalone): - include_dirs = self._preprocess_dirs(eci.include_dirs) + include_dirs = self._preprocess_include_dirs(eci.include_dirs) args = self._includedirs(include_dirs) if standalone: extra = self.standalone_only Modified: pypy/trunk/pypy/translator/platform/maemo.py ============================================================================== --- pypy/trunk/pypy/translator/platform/maemo.py (original) +++ pypy/trunk/pypy/translator/platform/maemo.py Wed Mar 31 14:38:29 2010 @@ -42,7 +42,7 @@ self.copied_cache[dir_from] = new_dirpath return new_dirpath - def _preprocess_dirs(self, include_dirs): + def _preprocess_include_dirs(self, include_dirs): """ Tweak includedirs so they'll be available through scratchbox """ res_incl_dirs = [] Modified: pypy/trunk/pypy/translator/platform/posix.py ============================================================================== --- pypy/trunk/pypy/translator/platform/posix.py (original) +++ pypy/trunk/pypy/translator/platform/posix.py Wed Mar 31 14:38:29 2010 @@ -45,10 +45,6 @@ cwd=str(exe_name.dirpath())) return exe_name - def _preprocess_dirs(self, include_dirs): - # hook for maemo - return include_dirs - def _pkg_config(self, lib, opt, default): try: ret, out, err = _run_subprocess("pkg-config", [lib, opt]) @@ -87,7 +83,7 @@ m.cfiles = rel_cfiles rel_includedirs = [pypyrel(incldir) for incldir in - self._preprocess_dirs(eci.include_dirs)] + self._preprocess_include_dirs(eci.include_dirs)] m.comment('automatically generated makefile') definitions = [ Modified: pypy/trunk/pypy/translator/platform/windows.py ============================================================================== --- pypy/trunk/pypy/translator/platform/windows.py (original) +++ pypy/trunk/pypy/translator/platform/windows.py Wed Mar 31 14:38:29 2010 @@ -116,17 +116,6 @@ # The following symbol is used in c/src/stack.h self.cflags.append('/DMAX_STACK_SIZE=%d' % (stack_size - 1024)) - if hasattr(sys, 'exec_prefix'): - self.add_cpython_dirs = True - else: - # We are certainly running pypy-c - self.add_cpython_dirs = False - - 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] From xoraxax at codespeak.net Wed Mar 31 15:04:40 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 15:04:40 +0200 (CEST) Subject: [pypy-svn] r73210 - in pypy/branch/cpython-extension/pypy: rlib translator/c Message-ID: <20100331130440.EC19A282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 15:04:39 2010 New Revision: 73210 Modified: pypy/branch/cpython-extension/pypy/rlib/exports.py pypy/branch/cpython-extension/pypy/translator/c/genc.py Log: Introduce and use exports.clear. Modified: pypy/branch/cpython-extension/pypy/rlib/exports.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rlib/exports.py (original) +++ pypy/branch/cpython-extension/pypy/rlib/exports.py Wed Mar 31 15:04:39 2010 @@ -1,10 +1,13 @@ from pypy.rpython.lltypesystem.lltype import typeOf, ContainerType -EXPORTS_names = set() -EXPORTS_obj2name = {} - def export_struct(name, struct): assert name not in EXPORTS_names, "Duplicate export " + name assert isinstance(typeOf(struct), ContainerType) EXPORTS_names.add(name) EXPORTS_obj2name[struct] = name + +def clear(): + global EXPORTS_names, EXPORTS_obj2name + EXPORTS_names = set() + EXPORTS_obj2name = {} +clear() Modified: pypy/branch/cpython-extension/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/genc.py Wed Mar 31 15:04:39 2010 @@ -171,6 +171,7 @@ for obj in exports.EXPORTS_obj2name.keys(): db.getcontainernode(obj) + exports.clear() db.complete() self.collect_compilation_info(db) From xoraxax at codespeak.net Wed Mar 31 15:05:45 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 15:05:45 +0200 (CEST) Subject: [pypy-svn] r73211 - pypy/branch/cpython-extension/pypy/rpython/lltypesystem Message-ID: <20100331130545.60200282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 15:05:43 2010 New Revision: 73211 Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/lltype.py Log: Allow for _compilation_info fields on _structs. Modified: pypy/branch/cpython-extension/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/branch/cpython-extension/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/branch/cpython-extension/pypy/rpython/lltypesystem/lltype.py Wed Mar 31 15:05:43 2010 @@ -1412,7 +1412,7 @@ class _struct(_parentable): _kind = "structure" - __slots__ = ('_hash_cache_',) + __slots__ = ('_hash_cache_', '_compilation_info') def __new__(self, TYPE, n=None, initialization=None, parent=None, parentindex=None): my_variety = _struct_variety(TYPE._names) From xoraxax at codespeak.net Wed Mar 31 15:06:53 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 15:06:53 +0200 (CEST) Subject: [pypy-svn] r73212 - pypy/branch/cpython-extension/pypy/translator/c Message-ID: <20100331130653.9AC0D282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 15:06:52 2010 New Revision: 73212 Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py Log: Introduce hack to translate prebuilt llhelper fnptrs. Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/node.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/node.py Wed Mar 31 15:06:52 2010 @@ -925,7 +925,11 @@ assert fnobj.external == 'CPython' return [CExternalFunctionCodeGenerator(fnobj, db)] else: - raise ValueError, "don't know how to generate code for %r" % (fnobj,) + # HACK! sandboxing missing here + graph = db.translator.annotator.bookkeeper.getdesc(fnobj._callable).getuniquegraph() + exception_policy = getattr(fnobj, 'exception_policy', None) + return [FunctionCodeGenerator(graph, db, exception_policy, functionname)] + #raise ValueError, "don't know how to generate code for %r" % (fnobj,) class ExtType_OpaqueNode(ContainerNode): nodekind = 'rpyopaque' From xoraxax at codespeak.net Wed Mar 31 15:29:02 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 15:29:02 +0200 (CEST) Subject: [pypy-svn] r73213 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331132902.ED2D7282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 15:29:01 2010 New Revision: 73213 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Further translation fixes, relax_sig_check also for wrappers used in llhelpers, export structs of global objects, use eci. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 15:29:01 2010 @@ -112,6 +112,7 @@ if wrapper is None: wrapper = make_wrapper(space, self.callable) self._wrapper = wrapper + wrapper.relax_sig_check = True return wrapper def cpython_api(argtypes, restype, borrowed=False, error=_NOT_SPECIFIED, external=True): @@ -220,6 +221,10 @@ 'PyBaseObject_Type#': ('PyTypeObject*', 'space.w_object'), } +def get_structtype_for_ctype(ctype): + from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr + return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr}[ctype] + # It is important that these PyObjects are allocated in a raw fashion # Thus we cannot save a forward pointer to the wrapped object # So we need a forward and backward mapping in our State instance @@ -406,7 +411,7 @@ return modulename.new(ext='') -def generate_macros(export_symbols, rename=True): +def generate_macros(export_symbols, rename=True, do_deref=True): pypy_macros = [] renamed_symbols = [] for name in export_symbols: @@ -415,6 +420,7 @@ continue if "#" in name: deref = "*" + if not do_deref and not rename: continue else: deref = "" if not rename: continue @@ -471,6 +477,9 @@ else: assert code is None + if not build_bridge: + kwds["includes"] = ['Python.h'] # this is our Python.h + eci = ExternalCompilationInfo( include_dirs=include_dirs, separate_module_files=[include_dir / "varargwrapper.c", @@ -488,11 +497,11 @@ export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) db = LowLevelDatabase() - generate_macros(export_symbols, rename) + generate_macros(export_symbols, rename, False) generate_decls_and_callbacks(db, False) - eci = build_eci(False, export_symbols) # XXX use eci + eci = build_eci(False, export_symbols) bootstrap_types(space) @@ -502,7 +511,10 @@ if rename: name = name.replace('Py', 'PyPy') w_obj = eval(expr) - export_struct(name, make_ref(space, w_obj)._obj) + struct_ptr = make_ref(space, w_obj) + struct = rffi.cast(get_structtype_for_ctype(type), struct_ptr)._obj + struct._compilation_info = eci + export_struct(name, struct) for name, func in FUNCTIONS.iteritems(): deco = entrypoint("cpyext", func.argtypes, name, relax=True) From benjamin at codespeak.net Wed Mar 31 16:27:03 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 16:27:03 +0200 (CEST) Subject: [pypy-svn] r73214 - pypy/trunk/pypy/objspace/flow Message-ID: <20100331142703.F0617282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 16:26:59 2010 New Revision: 73214 Modified: pypy/trunk/pypy/objspace/flow/objspace.py Log: raise a flow space RuntimeError when prebuilt_recursion_error is accessed Modified: pypy/trunk/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/flow/objspace.py (original) +++ pypy/trunk/pypy/objspace/flow/objspace.py Wed Mar 31 16:26:59 2010 @@ -457,7 +457,7 @@ # XXX same as w_KeyboardInterrupt() raise RuntimeError("the interpreter raises RuntimeError during " "flow graph construction") - w_RuntimeError = property(w_RuntimeError) + w_RuntimeError = prebuilt_recursion_error = property(w_RuntimeError) # the following gives us easy access to declare more for applications: NOT_REALLY_CONST = { From getxsick at codespeak.net Wed Mar 31 16:36:24 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Wed, 31 Mar 2010 16:36:24 +0200 (CEST) Subject: [pypy-svn] r73215 - pypy/trunk/pypy/module/_locale/test Message-ID: <20100331143624.E5728282BD8@codespeak.net> Author: getxsick Date: Wed Mar 31 16:36:23 2010 New Revision: 73215 Modified: pypy/trunk/pypy/module/_locale/test/test_locale.py Log: avoid to skip the tests on only UTF-8 oriented systems Modified: pypy/trunk/pypy/module/_locale/test/test_locale.py ============================================================================== --- pypy/trunk/pypy/module/_locale/test/test_locale.py (original) +++ pypy/trunk/pypy/module/_locale/test/test_locale.py Wed Mar 31 16:36:23 2010 @@ -22,8 +22,15 @@ current = _locale.setlocale(_locale.LC_ALL) try: try: - _locale.setlocale(_locale.LC_ALL, - space.str_w(cls.w_language_en)) + # some systems are only UTF-8 oriented + try: + _locale.setlocale(_locale.LC_ALL, + space.str_w(cls.w_language_en)) + except _locale.Error: + _locale.setlocale(_locale.LC_ALL, + space.str_w(cls.w_language_utf8)) + cls.w_language_en = cls.w_language_utf8 + _locale.setlocale(_locale.LC_ALL, space.str_w(cls.w_language_pl)) except _locale.Error: @@ -111,10 +118,11 @@ assert string.lowercase == lcase assert string.uppercase == ucase - _locale.setlocale(_locale.LC_ALL, self.language_en) + if self.language_en != self.language_utf8: + _locale.setlocale(_locale.LC_ALL, self.language_en) - assert string.lowercase != lcase - assert string.uppercase != ucase + assert string.lowercase != lcase + assert string.uppercase != ucase def test_localeconv(self): import _locale From xoraxax at codespeak.net Wed Mar 31 17:03:49 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 17:03:49 +0200 (CEST) Subject: [pypy-svn] r73216 - in pypy/branch/cpython-extension/pypy/translator/c: . test Message-ID: <20100331150349.5C47B282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 17:03:47 2010 New Revision: 73216 Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Log: Clean up hack a bit and write a test for it. Modified: pypy/branch/cpython-extension/pypy/translator/c/node.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/node.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/node.py Wed Mar 31 17:03:47 2010 @@ -924,12 +924,10 @@ else: assert fnobj.external == 'CPython' return [CExternalFunctionCodeGenerator(fnobj, db)] + elif hasattr(fnobj._callable, "c_name"): + return [] else: - # HACK! sandboxing missing here - graph = db.translator.annotator.bookkeeper.getdesc(fnobj._callable).getuniquegraph() - exception_policy = getattr(fnobj, 'exception_policy', None) - return [FunctionCodeGenerator(graph, db, exception_policy, functionname)] - #raise ValueError, "don't know how to generate code for %r" % (fnobj,) + raise ValueError, "don't know how to generate code for %r" % (fnobj,) class ExtType_OpaqueNode(ContainerNode): nodekind = 'rpyopaque' Modified: pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py (original) +++ pypy/branch/cpython-extension/pypy/translator/c/test/test_genc.py Wed Mar 31 17:03:47 2010 @@ -429,3 +429,53 @@ t.view() assert ' BarStruct ' in t.driver.cbuilder.c_source_filename.read() +def test_recursive_llhelper(): + from pypy.rpython.annlowlevel import llhelper + from pypy.rpython.lltypesystem import lltype + from pypy.rlib.objectmodel import specialize + from pypy.rlib.nonconst import NonConstant + FT = lltype.ForwardReference() + FTPTR = lltype.Ptr(FT) + STRUCT = lltype.Struct("foo", ("bar", FTPTR)) + FT.become(lltype.FuncType([lltype.Ptr(STRUCT)], lltype.Signed)) + + class A: + def __init__(self, func, name): + self.func = func + self.name = name + def _freeze_(self): + return True + @specialize.memo() + def make_func(self): + f = getattr(self, "_f", None) + if f is not None: + return f + f = lambda *args: self.func(*args) + f.c_name = self.name + f.relax_sig_check = True + f.__name__ = "WRAP%s" % (self.name, ) + self._f = f + return f + def get_llhelper(self): + return llhelper(FTPTR, self.make_func()) + def f(s): + if s.bar == t.bar: + lltype.free(s, flavor="raw") + return 1 + lltype.free(s, flavor="raw") + return 0 + def g(x): + return 42 + def chooser(x): + s = lltype.malloc(STRUCT, flavor="raw") + if x: + s.bar = llhelper(FTPTR, a_f.make_func()) + else: + s.bar = llhelper(FTPTR, a_g.make_func()) + return f(s) + a_f = A(f, "f") + a_g = A(g, "g") + t = lltype.malloc(STRUCT, flavor="raw") + t.bar = llhelper(FTPTR, a_f.make_func()) + fn = compile(chooser, [bool]) + assert fn(True) From xoraxax at codespeak.net Wed Mar 31 17:04:42 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 17:04:42 +0200 (CEST) Subject: [pypy-svn] r73217 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331150442.8B7F4282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 17:04:41 2010 New Revision: 73217 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Fix export symbols if renaming is disabled, always declare data fields but enclose them by an ifndef. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 17:04:41 2010 @@ -365,7 +365,7 @@ struct PyPyAPI* pypyAPI = &_pypyAPI; """ % dict(members=structmembers) - functions = generate_decls_and_callbacks(db, True) + functions = generate_decls_and_callbacks(db) global_objects = [] for name, (type, expr) in GLOBALS.iteritems(): @@ -430,11 +430,12 @@ newname = name pypy_macros.append('#define %s %s%s' % (name, deref, newname)) renamed_symbols.append(newname) - export_symbols[:] = renamed_symbols + if rename: + export_symbols[:] = renamed_symbols pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros)) -def generate_decls_and_callbacks(db, declare_globals): +def generate_decls_and_callbacks(db): # implement function callbacks and generate function decls functions = [] pypy_decls = [] @@ -451,9 +452,10 @@ pypy_decls.append(header + ";") body = "{ return _pypyAPI.%s(%s); }" % (name, callargs) functions.append('%s\n%s\n' % (header, body)) - if declare_globals: - for name, (typ, expr) in GLOBALS.iteritems(): - pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name.replace("#", ""))) + pypy_decls.append("#ifndef PYPY_STANDALONE\n") + for name, (typ, expr) in GLOBALS.iteritems(): + pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name.replace("#", ""))) + pypy_decls.append("#endif\n") pypy_decl_h = udir.join('pypy_decl.h') pypy_decl_h.write('\n'.join(pypy_decls)) @@ -464,20 +466,17 @@ kwds = {} export_symbols_eci = export_symbols[:] - if sys.platform == "win32": - # '%s' undefined; assuming extern returning int - kwds["compile_extra"] = ["/we4013"] - else: - kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] - if build_bridge: assert code is not None + if sys.platform == "win32": + # '%s' undefined; assuming extern returning int + kwds["compile_extra"] = ["/we4013"] + else: + kwds["compile_extra"] = ["-Werror=implicit-function-declaration"] kwds["separate_module_sources"] = [code] export_symbols_eci.append('pypyAPI') else: assert code is None - - if not build_bridge: kwds["includes"] = ['Python.h'] # this is our Python.h eci = ExternalCompilationInfo( @@ -499,7 +498,7 @@ generate_macros(export_symbols, rename, False) - generate_decls_and_callbacks(db, False) + generate_decls_and_callbacks(db) eci = build_eci(False, export_symbols) From benjamin at codespeak.net Wed Mar 31 17:36:32 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 17:36:32 +0200 (CEST) Subject: [pypy-svn] r73220 - pypy/trunk/pypy/objspace/std Message-ID: <20100331153632.38D19282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 17:36:30 2010 New Revision: 73220 Modified: pypy/trunk/pypy/objspace/std/objspace.py pypy/trunk/pypy/objspace/std/register_all.py Log: extra comparisons must be added each time multimethods are registered Modified: pypy/trunk/pypy/objspace/std/objspace.py ============================================================================== --- pypy/trunk/pypy/objspace/std/objspace.py (original) +++ pypy/trunk/pypy/objspace/std/objspace.py Wed Mar 31 17:36:30 2010 @@ -89,7 +89,6 @@ def _install_multimethods(self): """Install all the MultiMethods into the space instance.""" - model.add_extra_comparisons() for name, mm in model.MM.__dict__.items(): if not isinstance(mm, model.StdObjSpaceMultiMethod): continue Modified: pypy/trunk/pypy/objspace/std/register_all.py ============================================================================== --- pypy/trunk/pypy/objspace/std/register_all.py (original) +++ pypy/trunk/pypy/objspace/std/register_all.py Wed Mar 31 17:36:30 2010 @@ -44,6 +44,8 @@ func = hack_func_by_name(funcname, namespaces) func.register(obj, *l) + model.add_extra_comparisons() + def hack_func_by_name(funcname, namespaces): for ns in namespaces: From fijal at codespeak.net Wed Mar 31 17:55:53 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 31 Mar 2010 17:55:53 +0200 (CEST) Subject: [pypy-svn] r73221 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100331155553.AFA92282BD8@codespeak.net> Author: fijal Date: Wed Mar 31 17:55:52 2010 New Revision: 73221 Added: pypy/extradoc/talk/oopsla2010/paper.txt - copied, changed from r73125, pypy/extradoc/talk/oopsla2010/paper3.txt Removed: pypy/extradoc/talk/oopsla2010/paper2.txt pypy/extradoc/talk/oopsla2010/paper3.txt Log: Remove other approaches Copied: pypy/extradoc/talk/oopsla2010/paper.txt (from r73125, pypy/extradoc/talk/oopsla2010/paper3.txt) ============================================================================== --- pypy/extradoc/talk/oopsla2010/paper3.txt (original) +++ pypy/extradoc/talk/oopsla2010/paper.txt Wed Mar 31 17:55:52 2010 @@ -48,3 +48,4 @@ we created a tiny language and wrote interpreter for it in RPython to showcase benefits of our that can also be applied on a large scale. + From xoraxax at codespeak.net Wed Mar 31 18:04:46 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 18:04:46 +0200 (CEST) Subject: [pypy-svn] r73222 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331160446.61E19282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 18:04:44 2010 New Revision: 73222 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Introduce FUNCTIONS_STATIC, this is necessary for a hack. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 18:04:44 2010 @@ -9,7 +9,6 @@ from pypy.rpython.lltypesystem import ll2ctypes from pypy.rpython.annlowlevel import llhelper from pypy.rlib.objectmodel import we_are_translated -from pypy.translator.c.database import LowLevelDatabase from pypy.translator.tool.cbuild import ExternalCompilationInfo from pypy.tool.udir import udir from pypy.translator import platform @@ -190,6 +189,8 @@ unwrapper_raise = make_unwrapper(False) if external: FUNCTIONS[func.func_name] = api_function + else: + FUNCTIONS_STATIC[func.func_name] = api_function INTERPLEVEL_API[func.func_name] = unwrapper_catch # used in tests return unwrapper_raise # used in 'normal' RPython code. return decorate @@ -209,6 +210,7 @@ INTERPLEVEL_API = {} FUNCTIONS = {} +FUNCTIONS_STATIC = {} FUNCTIONS_C = {} TYPES = {} GLOBALS = { @@ -346,6 +348,7 @@ from pypy.module.cpyext.pyobject import make_ref export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) + from pypy.translator.c.database import LowLevelDatabase db = LowLevelDatabase() generate_macros(export_symbols, rename) @@ -494,6 +497,7 @@ from pypy.module.cpyext.pyobject import make_ref export_symbols = list(FUNCTIONS) + list(FUNCTIONS_C) + list(GLOBALS) + from pypy.translator.c.database import LowLevelDatabase db = LowLevelDatabase() generate_macros(export_symbols, rename, False) @@ -518,6 +522,8 @@ for name, func in FUNCTIONS.iteritems(): deco = entrypoint("cpyext", func.argtypes, name, relax=True) deco(func.get_wrapper(space)) + for name, func in FUNCTIONS_STATIC.iteritems(): + func.get_wrapper(space).c_name = name @unwrap_spec(ObjSpace, str, str) From xoraxax at codespeak.net Wed Mar 31 18:22:20 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 18:22:20 +0200 (CEST) Subject: [pypy-svn] r73223 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331162220.E6C07282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 18:22:19 2010 New Revision: 73223 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Also remove # signs from export symbols if no renaming takes place. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 18:22:19 2010 @@ -435,6 +435,8 @@ renamed_symbols.append(newname) if rename: export_symbols[:] = renamed_symbols + else: + export_symbols = [sym.replace("#", "") for sym in export_symbols] pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros)) From fijal at codespeak.net Wed Mar 31 18:30:31 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 31 Mar 2010 18:30:31 +0200 (CEST) Subject: [pypy-svn] r73224 - pypy/extradoc/talk/oopsla2010 Message-ID: <20100331163031.2F243282BD8@codespeak.net> Author: fijal Date: Wed Mar 31 18:30:29 2010 New Revision: 73224 Modified: pypy/extradoc/talk/oopsla2010/paper.txt Log: a bit of progress Modified: pypy/extradoc/talk/oopsla2010/paper.txt ============================================================================== --- pypy/extradoc/talk/oopsla2010/paper.txt (original) +++ pypy/extradoc/talk/oopsla2010/paper.txt Wed Mar 31 18:30:29 2010 @@ -48,4 +48,20 @@ we created a tiny language and wrote interpreter for it in RPython to showcase benefits of our that can also be applied on a large scale. +As a result, we can remove the frame overhead costs almost completely +from the running program. There are some corner-cases, require by python +language specification, that make frame escape via traceback (if exception +exits jitted part of the code). In that case we allocate the frame and +put all elements there. However, this still avoids using frame for all +operations, as the interpreter would do. + +Performance gains are significant (XXX actually measure how significant). +XXX + +Related work +============ + +Technical background +==================== + From getxsick at codespeak.net Wed Mar 31 21:49:09 2010 From: getxsick at codespeak.net (getxsick at codespeak.net) Date: Wed, 31 Mar 2010 21:49:09 +0200 (CEST) Subject: [pypy-svn] r73229 - pypy/trunk/pypy/module/_ssl Message-ID: <20100331194909.B9347282BD8@codespeak.net> Author: getxsick Date: Wed Mar 31 21:49:08 2010 New Revision: 73229 Modified: pypy/trunk/pypy/module/_ssl/interp_ssl.py Log: add missing header file Modified: pypy/trunk/pypy/module/_ssl/interp_ssl.py ============================================================================== --- pypy/trunk/pypy/module/_ssl/interp_ssl.py (original) +++ pypy/trunk/pypy/module/_ssl/interp_ssl.py Wed Mar 31 21:49:08 2010 @@ -18,10 +18,11 @@ # need of winsock2. Remove this when separate compilation is # available... 'winsock2.h', - 'openssl/ssl.h'] + 'openssl/ssl.h', + 'openssl/err.h'] else: libraries = ['ssl', 'crypto'] - includes = ['openssl/ssl.h'] + includes = ['openssl/ssl.h', 'openssl/err.h'] eci = ExternalCompilationInfo( libraries = libraries, @@ -140,7 +141,7 @@ ssl_external('SSL_get_error', [SSL_P, rffi.INT], rffi.INT) ssl_external('ERR_get_error', [], rffi.INT) -ssl_external('ERR_error_string', [rffi.INT, rffi.CCHARP], rffi.CCHARP) +ssl_external('ERR_error_string', [rffi.ULONG, rffi.CCHARP], rffi.CCHARP) ssl_external('SSL_get_peer_certificate', [SSL_P], X509_P) ssl_external('X509_get_subject_name', [X509_P], X509_NAME_P) ssl_external('X509_get_issuer_name', [X509_P], X509_NAME_P) From arigo at codespeak.net Wed Mar 31 22:41:15 2010 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 31 Mar 2010 22:41:15 +0200 (CEST) Subject: [pypy-svn] r73230 - pypy/trunk/pypy/interpreter Message-ID: <20100331204115.D62FF282BD8@codespeak.net> Author: arigo Date: Wed Mar 31 22:41:14 2010 New Revision: 73230 Modified: pypy/trunk/pypy/interpreter/gateway.py Log: Fix a stackless test in module/_rawffi, by catching the RPython-level RuntimeError and raising an OperationError(w_RuntimeError) instead. It looks like a good idea more generally. Modified: pypy/trunk/pypy/interpreter/gateway.py ============================================================================== --- pypy/trunk/pypy/interpreter/gateway.py (original) +++ pypy/trunk/pypy/interpreter/gateway.py Wed Mar 31 22:41:14 2010 @@ -576,6 +576,8 @@ except rstackovf.StackOverflow, e: rstackovf.check_stack_overflow() raise space.prebuilt_recursion_error + except RuntimeError: # not on top of py.py + raise OperationError(space.w_RuntimeError, space.w_None) # (verbose) performance hack below From benjamin at codespeak.net Wed Mar 31 23:03:57 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 23:03:57 +0200 (CEST) Subject: [pypy-svn] r73231 - pypy/trunk/pypy/interpreter Message-ID: <20100331210357.52088282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 23:03:55 2010 New Revision: 73231 Modified: pypy/trunk/pypy/interpreter/pyopcode.py Log: fold imports Modified: pypy/trunk/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyopcode.py (original) +++ pypy/trunk/pypy/interpreter/pyopcode.py Wed Mar 31 23:03:55 2010 @@ -7,18 +7,16 @@ import sys from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.baseobjspace import UnpackValueError, Wrappable -from pypy.interpreter import gateway, function, eval -from pypy.interpreter import pyframe, pytraceback +from pypy.interpreter import gateway, function, eval, pyframe, pytraceback from pypy.interpreter.pycode import PyCode from pypy.tool.sourcetools import func_with_new_name from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib import jit +from pypy.rlib import jit, rstackovf from pypy.rlib.rarithmetic import r_uint, intmask -from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT -from pypy.tool.stdlib_opcode import unrolling_opcode_descs -from pypy.tool.stdlib_opcode import opcode_method_names from pypy.rlib.unroll import unrolling_iterable -from pypy.rlib import rstackovf +from pypy.tool.stdlib_opcode import (opcodedesc, HAVE_ARGUMENT, + unrolling_opcode_descs, + opcode_method_names) def unaryoperation(operationname): """NOT_RPYTHON""" From benjamin at codespeak.net Wed Mar 31 23:16:01 2010 From: benjamin at codespeak.net (benjamin at codespeak.net) Date: Wed, 31 Mar 2010 23:16:01 +0200 (CEST) Subject: [pypy-svn] r73232 - pypy/trunk/pypy/interpreter Message-ID: <20100331211601.7DA5E282BD8@codespeak.net> Author: benjamin Date: Wed Mar 31 23:15:59 2010 New Revision: 73232 Modified: pypy/trunk/pypy/interpreter/pyframe.py Log: use stdlib_opcode Modified: pypy/trunk/pypy/interpreter/pyframe.py ============================================================================== --- pypy/trunk/pypy/interpreter/pyframe.py (original) +++ pypy/trunk/pypy/interpreter/pyframe.py Wed Mar 31 23:15:59 2010 @@ -7,18 +7,18 @@ from pypy.interpreter.error import OperationError, operationerrfmt from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter import pytraceback -import opcode from pypy.rlib.objectmodel import we_are_translated, instantiate from pypy.rlib.jit import hint from pypy.rlib.debug import make_sure_not_resized from pypy.rlib import jit +from pypy.tool import stdlib_opcode # Define some opcodes used g = globals() for op in '''DUP_TOP POP_TOP SETUP_LOOP SETUP_EXCEPT SETUP_FINALLY POP_BLOCK END_FINALLY'''.split(): - g[op] = opcode.opmap[op] -HAVE_ARGUMENT = opcode.HAVE_ARGUMENT + g[op] = stdlib_opcode.opmap[op] +HAVE_ARGUMENT = stdlib_opcode.HAVE_ARGUMENT class PyFrame(eval.Frame): """Represents a frame for a regular Python function @@ -541,7 +541,7 @@ if delta_iblock < min_delta_iblock: min_delta_iblock = delta_iblock - if op >= opcode.HAVE_ARGUMENT: + if op >= stdlib_opcode.HAVE_ARGUMENT: addr += 3 else: addr += 1 From fijal at codespeak.net Wed Mar 31 23:38:03 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 31 Mar 2010 23:38:03 +0200 (CEST) Subject: [pypy-svn] r73233 - pypy/branch/cpython-extension/pypy/module/cpyext/include Message-ID: <20100331213803.7BE5F282BD8@codespeak.net> Author: fijal Date: Wed Mar 31 23:38:01 2010 New Revision: 73233 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Log: include stdarg as well Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h Wed Mar 31 23:38:01 2010 @@ -24,6 +24,7 @@ #include "object.h" +#include #include #include #include From fijal at codespeak.net Wed Mar 31 23:38:52 2010 From: fijal at codespeak.net (fijal at codespeak.net) Date: Wed, 31 Mar 2010 23:38:52 +0200 (CEST) Subject: [pypy-svn] r73234 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331213852.73175282BD8@codespeak.net> Author: fijal Date: Wed Mar 31 23:38:50 2010 New Revision: 73234 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: export a bit more exceptions Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 23:38:50 2010 @@ -217,12 +217,14 @@ 'Py_None': ('PyObject*', 'space.w_None'), 'Py_True': ('PyObject*', 'space.w_True'), 'Py_False': ('PyObject*', 'space.w_False'), - 'PyExc_Exception': ('PyObject*', 'space.w_Exception'), - 'PyExc_TypeError': ('PyObject*', 'space.w_TypeError'), 'PyType_Type#': ('PyTypeObject*', 'space.w_type'), 'PyBaseObject_Type#': ('PyTypeObject*', 'space.w_object'), } +for exc_name in ['TypeError', 'ValueError', 'KeyError', 'Exception', + 'BaseException']: + GLOBALS['PyExc_' + exc_name] = ('PyObject*', 'space.w_' + exc_name) + def get_structtype_for_ctype(ctype): from pypy.module.cpyext.typeobjectdefs import PyTypeObjectPtr return {"PyObject*": PyObject, "PyTypeObject*": PyTypeObjectPtr}[ctype] From xoraxax at codespeak.net Wed Mar 31 23:44:21 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 23:44:21 +0200 (CEST) Subject: [pypy-svn] r73235 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331214421.28B97282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 23:44:19 2010 New Revision: 73235 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py pypy/branch/cpython-extension/pypy/module/cpyext/state.py Log: Correctly init r2w mapping at runtime. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/__init__.py Wed Mar 31 23:44:19 2010 @@ -26,6 +26,8 @@ space.setattr(space.wrap(self), space.wrap('api_lib'), space.wrap(state.api_lib)) + else: + state.init_r2w_from_w2r() # import these modules to register api functions by side-effect import pypy.module.cpyext.pyobject Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Wed Mar 31 23:44:19 2010 @@ -20,6 +20,17 @@ self.exc_type = None self.exc_value = None + def _freeze_(self): + assert not self.borrowed_objects and not self.borrow_mapping + self.py_objects_r2w.clear() # is not valid anymore after translation + return False + + def init_r2w_from_w2r(self): + from pypy.module.cpyext.api import ADDR + for w_obj, obj in self.py_objects_w2r.items(): + ptr = rffi.cast(ADDR, obj) + self.py_objects_r2w[ptr] = w_obj + def set_exception(self, w_type, w_value): self.clear_exception() self.exc_type = w_type From xoraxax at codespeak.net Wed Mar 31 23:57:26 2010 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Wed, 31 Mar 2010 23:57:26 +0200 (CEST) Subject: [pypy-svn] r73236 - pypy/branch/cpython-extension/pypy/module/cpyext Message-ID: <20100331215726.7E2B2282BD8@codespeak.net> Author: xoraxax Date: Wed Mar 31 23:57:25 2010 New Revision: 73236 Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py Log: Really rename the symbols. Should be refactored to return the export symbols. Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py ============================================================================== --- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original) +++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Wed Mar 31 23:57:25 2010 @@ -438,7 +438,7 @@ if rename: export_symbols[:] = renamed_symbols else: - export_symbols = [sym.replace("#", "") for sym in export_symbols] + export_symbols[:] = [sym.replace("#", "") for sym in export_symbols] pypy_macros_h = udir.join('pypy_macros.h') pypy_macros_h.write('\n'.join(pypy_macros))